
DeepSeek+Dify查询数据库
之前有小伙伴咨询,Dify不支持直连数据库,如何做到通过自然语义给大模型然后返回对应的查询数据?收到这个留言的时候,脑海里就已经有了一个大致的方案,流程如下图:首先利用帮我准备数据库表结构和需要插入的数据然后通用利用DeepSeek帮我生成一个暴露接口用于查询数据库的服务,用python写。
之前有小伙伴咨询,Dify不支持直连数据库,如何做到通过自然语义给大模型然后返回对应的查询数据?
收到这个留言的时候,脑海里就已经有了一个大致的方案,流程如下图:
首先利用DeepSeek帮我准备数据库表结构和需要插入的数据
相关的建表数据我贴在下面:
# 创建班级表
CREATE TABLE classes (
class_id INT AUTO_INCREMENT PRIMARY KEY,
class_name VARCHAR(50) NOT NULL
);
# 创建用户表
CREATE TABLE users (
user_id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
class_id INT,
FOREIGN KEY (class_id) REFERENCES classes(class_id)
);
# 插入班级数据
INSERT INTO classes (class_name) VALUES
('Class A'),
('Class B'),
('Class C'),
('Class D');
# 插入用户数据
INSERT INTO users (username, email, class_id) VALUES
('Alice', 'alice@example.com', 1),
('Bob', 'bob@example.com', 2),
('Charlie', 'charlie@example.com', 3),
('David', 'david@example.com', 4),
('Eve', 'eve@example.com', 1),
('Frank', 'frank@example.com', 2),
('Grace', 'grace@example.com', 3),
('Hank', 'hank@example.com', 4),
('Ivy', 'ivy@example.com', 1),
('Jack', 'jack@example.com', 2);
然后通用利用DeepSeek帮我生成一个暴露接口用于查询数据库的服务,用python写
整理后的python代码我贴在下面:
from flask import Flask, request, jsonify
import pymysql
import re
# 创建 Flask 应用
app = Flask(__name__)
# 数据库连接配置
DB_CONFIG = {
'host': 'localhost',
'user': 'test', # 替换为你的数据库用户名
'password': '123456', # 替换为你的数据库密码
'database': 'test', # 替换为你的数据库名称
'cursorclass': pymysql.cursors.DictCursor
}
# 定义接口:执行 SQL 查询
@app.route('/query', methods=['POST'])
def execute_query():
# 获取客户端传递的 SQL 语句
data = request.json
if not data or 'sql' not in data:
return jsonify({'error': 'Missing SQL statement in request body'}), 400
sql = data['sql']
# 简单的 SQL 语句验证(防止恶意操作)
if not re.match(r'^SELECT\s', sql, re.IGNORECASE):
return jsonify({'error': 'Only SELECT queries are allowed'}), 400
try: # 连接数据库
connection = pymysql.connect(**DB_CONFIG)
with connection.cursor() as cursor:
# 执行 SQL 查询
cursor.execute(sql)
result = cursor.fetchall()
return jsonify(result)
except pymysql.MySQLError as e:
return jsonify({'error': str(e)}), 500
finally:
if connection:
connection.close()
# 启动服务
if __name__ == '__main__':
app.run(debug=True)
可以放在编辑器里面直接启动,也可以用命令行启动:
python .\server.py
开始配置工作流
创建一个单独的知识库,里面存放的就是我们的创建表结构的语句,可以是text格式也可以是markdown格式,这个都可以,我这边就很简单粗暴的直接扔建表语句进去,最好是带注释的,我演示用就简洁一点:
创建一个空的工作流
在【开始】节点添加“输入字段:content”
在【开始】节点后添加一个【知识检索】节点:
在【知识检索】节点后添加【LLM】节点:
【知识检索】节点的输出作为上下文传入,并在提示词内设置【开始】节点输入的"content"字段,以供LLM去做分析:
我设置的提示词也贴在下面,“{}”花括号内的是你需要在节点中设置的参数,参考上图显示的最终结果:
你是一个数据分析师,根据用户输入的{content}
需求以及检索到{上下文}
,生成对应的查询SQL,SQL必须经过严格的校验。
## 你可以使用的其他方法
用户输入类似于“求和”或“总和”时,则在sql语句中使用SUM()。
用户输入类似于“平均数”或“平均”时,在在sql语句中使用AVG()。
## 要求
1.如果用户输入的内容无法生成为sql语句,请直接说“抱歉,该命令无法形成数据库查询操作”。
2.当可以生成sql语句时,请确保输出的内容为完整正确的sql语句,不要输出此外的其他任何字符,确保你生成的内容用户可以直接执行查询操作。
3.对于字符串内容的查询请使用LIKE操作而不是等于操作。
4.请不要在回复中包括除sql语句之外的任何内容。
5.禁止中间过程输出。
6.输出的sql为一整行。
在【自然语言推导SQL语句LLM】节点后,添加【HTTP请求】节点,并在节点上添加API和查询参数(JSON格式),查询参数就是【自然语言推导SQL语句LLM】节点输出的SQL语句,参数名称"sql"可以根据上面的python代码中处理的字段名称来调整:
需要注意的是,Dify是我本地Docker部署的,然后这个查询接口也是我本地启动的,所以这个接口地址不能用127.0.0.1,需要改成host.docker.internal。
在【查询SQL结果请求】节点之后,就可以添加【结束】节点了,输出内容就是我们【查询SQL结果请求】的输出内容即可。因为输出的是JSON格式的数据,也可以让返回结果为表格等,但是需要额外的节点去做处理,在这儿就不在演示,感兴趣的小伙伴们可以在这个基础上再做优化调整。
感谢小伙伴们提供的留言问题,我这只是一种思路方案,还有一种方案就是,通过python代码连接Dify然后结合知识库解析自然语言并推导出对应的SQL语句提供给python去执行,这种方案和我提供的方案大同小异,都是可以实现效果。
上述只是一个简单的demo,只是为了跑通这个逻辑,实际使用的话,要做很多层的限制,对SQL的推导也需要做更多的条件分支和二次分析等节点,以提高准确性和可用性。
有需要不想动手重新操作的小伙伴也可以关注我公众号后,在公众号发送【1007】(发蓝色数字)获取DSL导出文件,你们直接导入Dify后,调整对应参数就能运行,然后再此基础上做优化,也希望你们有新的设计后也可以共享出来!
更多推荐
所有评论(0)