Files
012-kaopeilian/知识库/Dify工作流-知识点管理SQL.md
111 998211c483 feat: 初始化考培练系统项目
- 从服务器拉取完整代码
- 按框架规范整理项目结构
- 配置 Drone CI 测试环境部署
- 包含后端(FastAPI)、前端(Vue3)、管理端

技术栈: Vue3 + TypeScript + FastAPI + MySQL
2026-01-24 19:33:28 +08:00

7.8 KiB
Raw Blame History

Dify工作流 - 知识点管理SQL脚本

📋 工作流场景

流程:清空旧知识点 → Dify AI分析 → 生成新知识点


🔧 SQL脚本

1. 删除单个资料的所有知识点

DELETE FROM knowledge_points WHERE material_id = 34;

说明

  • 物理删除,不可恢复
  • 会删除资料ID为34的所有知识点
  • 自动提交事务

2. 使用变量的方式(推荐)

SET @material_id = 34;
DELETE FROM knowledge_points WHERE material_id = @material_id;
SELECT CONCAT('已删除资料 ', @material_id, ' 的所有知识点,共 ', ROW_COUNT(), ' 条') as result;

优点

  • 变量可以动态传入
  • 便于日志记录
  • 返回删除数量

3. 带验证的删除(完整版)

-- 步骤1查看删除前的数量
SELECT COUNT(*) as count_before 
FROM knowledge_points 
WHERE material_id = 34;

-- 步骤2执行删除
DELETE FROM knowledge_points WHERE material_id = 34;

-- 步骤3验证删除结果应该为0
SELECT COUNT(*) as count_after 
FROM knowledge_points 
WHERE material_id = 34;

4. 批量删除多个资料

DELETE FROM knowledge_points 
WHERE material_id IN (34, 35, 36);

SELECT ROW_COUNT() as total_deleted;

5. 条件删除仅删除AI生成的

-- 只删除AI生成的知识点保留手动添加的
DELETE FROM knowledge_points 
WHERE material_id = 34 
  AND source = 1;  -- source=1 表示AI生成

SELECT ROW_COUNT() as deleted_ai_generated;

🎯 Dify工作流集成

方案A使用SQL执行节点

节点配置

  • 节点类型:HTTP RequestCode
  • 数据库连接直连MySQL

SQL命令

DELETE FROM knowledge_points WHERE material_id = {{material_id}};

变量映射

  • {{material_id}}从上游节点传入的资料ID

方案B使用HTTP请求调用后端API

API端点

DELETE /api/v1/courses/materials/{material_id}/knowledge-points/batch

请求示例

curl -X DELETE \
  "http://kaopeilian-backend-dev:8000/api/v1/courses/materials/34/knowledge-points/batch" \
  -H "Authorization: Bearer {{api_token}}" \
  -H "Content-Type: application/json"

方案CPython代码节点

import pymysql

def delete_knowledge_points(material_id):
    """删除指定资料的所有知识点"""
    
    # 数据库连接
    conn = pymysql.connect(
        host='120.79.247.16',
        port=3307,
        user='root',
        password='nj861021',
        database='kaopeilian',
        charset='utf8mb4'
    )
    
    try:
        cursor = conn.cursor()
        
        # 执行删除
        sql = "DELETE FROM knowledge_points WHERE material_id = %s"
        cursor.execute(sql, (material_id,))
        
        # 获取删除数量
        deleted_count = cursor.rowcount
        
        # 提交事务
        conn.commit()
        
        return {
            "success": True,
            "deleted_count": deleted_count,
            "message": f"已删除资料 {material_id}{deleted_count} 个知识点"
        }
        
    except Exception as e:
        conn.rollback()
        return {
            "success": False,
            "error": str(e),
            "message": f"删除失败: {str(e)}"
        }
        
    finally:
        cursor.close()
        conn.close()

# Dify中调用
result = delete_knowledge_points(material_id={{material_id}})
return result

🔍 验证删除结果

查询语句

-- 检查是否还有剩余的知识点
SELECT COUNT(*) as remaining_count 
FROM knowledge_points 
WHERE material_id = 34;

-- 应该返回remaining_count = 0

⚠️ 注意事项

1. 外键约束影响

exam_mistakes表的影响

  • exam_mistakes.knowledge_point_id 外键约束:ON DELETE SET NULL
  • 删除知识点时,相关错题记录的 knowledge_point_id 会被设置为 NULL
  • 不会阻止删除操作

验证

-- 检查是否有错题记录引用
SELECT COUNT(*) as dependent_count
FROM exam_mistakes 
WHERE knowledge_point_id IN (
    SELECT id FROM knowledge_points WHERE material_id = 34
);

2. 数据恢复

⚠️ 警告:物理删除后无法恢复!

建议:删除前备份

-- 备份到临时表
CREATE TABLE knowledge_points_backup_20251017 AS
SELECT * FROM knowledge_points WHERE material_id = 34;

-- 删除
DELETE FROM knowledge_points WHERE material_id = 34;

-- 如需恢复
-- INSERT INTO knowledge_points SELECT * FROM knowledge_points_backup_20251017;

3. 并发问题

如果Dify工作流并发执行可能导致问题

解决方案:使用行锁

-- 开始事务
START TRANSACTION;

-- 锁定资料记录
SELECT * FROM course_materials WHERE id = 34 FOR UPDATE;

-- 删除知识点
DELETE FROM knowledge_points WHERE material_id = 34;

-- 提交
COMMIT;

📊 监控和日志

删除操作日志

-- 记录删除操作(可选)
INSERT INTO system_logs (
    level, type, message, 
    user_id, created_at
) VALUES (
    'INFO', 
    'database', 
    CONCAT('删除资料 ', 34, ' 的所有知识点,共 ', ROW_COUNT(), ' 条'),
    1,
    NOW()
);

🎬 完整工作流示例

Dify工作流配置

workflow:
  name: "重新生成资料知识点"
  
  nodes:
    - id: "1"
      name: "获取资料信息"
      type: "http_request"
      config:
        url: "/api/v1/courses/materials/{{material_id}}"
        method: "GET"
    
    - id: "2"
      name: "清空旧知识点"
      type: "code"
      config:
        code: |
          import pymysql
          conn = pymysql.connect(
              host='120.79.247.16', port=3307,
              user='root', password='nj861021',
              database='kaopeilian'
          )
          cursor = conn.cursor()
          cursor.execute(
              "DELETE FROM knowledge_points WHERE material_id = %s",
              (material_id,)
          )
          conn.commit()
          deleted = cursor.rowcount
          conn.close()
          return {"deleted_count": deleted}
    
    - id: "3"
      name: "AI分析生成知识点"
      type: "llm"
      config:
        prompt: "分析文档并提取知识点..."
    
    - id: "4"
      name: "保存新知识点"
      type: "http_request"
      config:
        url: "/api/v1/courses/{{course_id}}/knowledge-points/batch"
        method: "POST"

🔗 数据库连接信息

主机: 120.79.247.16
端口: 3307
数据库: kaopeilian
用户: root
密码: nj861021

📝 常见问题

Q1: 删除后前端还显示知识点?

原因:前端缓存

解决

// 前端刷新数据
await loadMaterialKnowledgePoints(materialId, true)  // 强制刷新

Q2: 删除失败,提示外键约束?

原因:有其他表引用这些知识点

解决

-- 检查依赖
SELECT * FROM exam_mistakes 
WHERE knowledge_point_id IN (
    SELECT id FROM knowledge_points WHERE material_id = 34
);

-- 如果有依赖,先清空外键或删除依赖记录

Q3: 需要批量删除多个资料的知识点?

-- 方法1IN子句
DELETE FROM knowledge_points 
WHERE material_id IN (34, 35, 36);

-- 方法2子查询根据课程ID
DELETE FROM knowledge_points 
WHERE material_id IN (
    SELECT id FROM course_materials 
    WHERE course_id = 1 AND is_deleted = 0
);

快速命令

仅删除(最简单)

DELETE FROM knowledge_points WHERE material_id = 34;

删除+验证

DELETE FROM knowledge_points WHERE material_id = 34;
SELECT COUNT(*) FROM knowledge_points WHERE material_id = 34;

删除+返回数量

DELETE FROM knowledge_points WHERE material_id = 34;
SELECT ROW_COUNT() as deleted;

推荐用法在Dify中使用最简单的单行命令

DELETE FROM knowledge_points WHERE material_id = {{material_id}};