使用Python接收用户输入查询MySQL,是否无需为每个场景编写独立SQL?
自然语言转MySQL查询需求实现方案
需求可行性结论
完全可以实现,不需要为每一种查询场景单独编写代码。你之前的预设选项方案属于硬编码适配,只能覆盖有限场景,要支持自由的自然语言查询,只需要引入「自然语言转SQL(NL2SQL)」能力即可。
核心实现思路
通过大语言模型(LLM)作为转换中间层,将用户输入的自然语言查询,结合你提供的固定表结构、关联规则,生成合法可执行的MySQL查询语句,再交给数据库执行返回结果即可。
具体实现步骤
1. 整理数据库元信息
先把你使用的三张表结构、关联关系整理成清晰的说明,用于给大模型传递规则:
- Departments表:字段包括
dept_no(主键)、dept_name - Employees表:字段包括
emp_no(主键)、f_name、l_name、dob、hire_date - Salaries表:字段包括
emp_no、salary、from_date(联合主键)、to_date - 表关联规则:
Employees.emp_no = Salaries.emp_no,如果需要关联部门表,补充员工和部门的关联字段即可(现有表结构未提供员工所属部门字段,可根据实际情况补充)
2. 构造大模型提示词
给大模型的提示词需要明确规则,避免生成不符合要求的内容,示例提示词如下:
你是一个MySQL语句生成工具,只需要输出纯SQL语句,不需要任何额外解释、注释、说明文字。
严格遵守以下规则:
- 只能生成SELECT查询语句,禁止生成其他任何类型的SQL语句
- 只能使用给定的三张表和对应的字段,禁止虚构不存在的表、字段
- 表关联必须使用正确的关联条件:
Employees.emp_no = Salaries.emp_no- 生成的SQL符合MySQL 8.0语法规范,数值类型字段对比不要加多余的单引号
现在根据用户的查询需求生成SQL:{用户输入的自然语言查询}
3. 执行生成的SQL并返回结果
调用大模型拿到生成的SQL后,先做基础校验(比如检查是否以SELECT开头,没有DROP、DELETE等危险关键词),再交给数据库执行即可。
简易代码示例
# 可替换为你使用的任意大模型SDK import openai from MySQLdb import connect from MySQLdb import Error # 大模型API配置 openai.api_key = "你的API密钥" def generate_sql(user_query): prompt = f"""你是一个MySQL语句生成工具,只需要输出纯SQL语句,不需要任何额外解释、注释、说明文字。 严格遵守以下规则: 1. 只能生成SELECT查询语句,禁止生成其他任何类型的SQL语句 2. 只能使用给定的三张表和对应的字段,禁止虚构不存在的表、字段: - Departments表:字段包括dept_no(主键)、dept_name - Employees表:字段包括emp_no(主键)、f_name、l_name、dob、hire_date - Salaries表:字段包括emp_no、salary、from_date(联合主键)、to_date 3. 表关联必须使用正确的关联条件:Employees.emp_no = Salaries.emp_no 4. 生成的SQL符合MySQL 8.0语法规范,数值类型字段对比不要加多余的单引号 现在根据用户的查询需求生成SQL:{user_query}""" response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}], temperature=0 ) return response.choices[0].message.content.strip() def execute_query(sql): try: with connect(host="localhost", user="root", password="root", database="employees") as connection: with connection.cursor() as cursor: cursor.execute(sql) records = cursor.fetchall() print(records) print("Total results found = ", cursor.rowcount) return records except Error as e: print(f"查询执行错误:{e}") return None if __name__ == "__main__": user_input = input("请输入查询需求:") sql = generate_sql(user_input) # 安全校验,只允许SELECT语句 if not sql.lower().startswith("select"): print("非法查询,仅支持查询操作") else: execute_query(sql)
注意事项
- 安全校验是必须的,防止大模型生成危险操作的SQL语句,除了限制仅允许SELECT外,还可以配置数据库账号的权限,仅开放查询权限,避免数据风险
- 如果SQL执行报错,可以把错误信息返回给大模型,让它重新生成SQL重试,提高成功率
- 如果你的查询场景比较简单,不想接入大模型,也可以通过正则表达式匹配用户输入里的关键词(比如薪资范围、名字、部门编号等),动态拼接SQL,不过这种方式只能覆盖有固定规律的查询,适配性不如大模型方案
内容的提问来源于stack exchange,提问作者esh9999
相关产品推荐
相关产品推荐

