Tutorial 6:Text-to-SQL 与查询处理¶
本教程围绕自然语言到结构化查询语言(Structured Query Language,SQL)的转换(Text-to-SQL)和查询改写,使用 SQLite 执行模型生成的只读查询。示例通过开放人工智能(OpenAI)兼容的应用程序编程接口(application programming interface,API)调用 DeepSeek;模型端点和模型名称可按实际服务调整。
1. 环境与 API 密钥¶
安装依赖:
| Bash | |
|---|---|
把 API 密钥放在环境变量中,不要写入 notebook、代码仓库或文档:
| Bash | |
|---|---|
在 Colab 中可使用 Secrets 管理密钥,避免把密钥写入共享单元格。
| Python | |
|---|---|
2. 准备 SQLite 数据库¶
创建学生、课程和选课三张表。外键约束表达学生与课程之间的多对多关系,选课表还保存成绩。
向模型提供必要的表结构和关系,避免模型猜测字段:
| Python | |
|---|---|
3. 请求模型生成 SQL¶
提示中明确方言、可用模式、只读限制和返回格式。示例限制为单条 SELECT,并要求只返回 SQL。
4. 检查並执行只读查询¶
下面的检查用于教学演示,不能作为生产环境的安全边界。正则表达式无法可靠解析任意 SQL,尤其是包含 CTE 或注释的语句。生产系统应使用只读数据库账户、数据库级只读模式、SQL 解析器、超时和资源限制。
| Python | |
|---|---|
SQLite 的 query_only 限制当前连接的写操作;仍应避免将不可信 SQL 用于具备更高权限的数据库连接。
5. Text-to-SQL 示例¶
5.1 条件筛选¶
问题:列出数据科学(DS)专业学生,并按姓名排序。生成的查询应包含 WHERE 和 ORDER BY。
| Python | |
|---|---|
也可先手写 SQL 验证预期结果:
5.2 分组聚合¶
问题:统计每个专业的学生人数。需要按 major 分组,并对学生记录计数。
5.3 表连接¶
问题:列出 Alice 选修的课程和成绩。需要连接学生、选课和课程表。
| SQL | |
|---|---|
5.4 查询改写与语义等价¶
子查询可以改写为连接。例如,找出选修至少一门课程的学生姓名:
对应的连接写法需要 DISTINCT,因为同一学生可能选修多门课程:
| SQL | |
|---|---|
可在同一数据库上比较两条查询的结果。查询改写不只要语法有效,还应保持重复值、空值和边界情况上的语义。
6. 练习:按课程计算平均成绩¶
查询每门课程的平均成绩,只保留平均成绩不低于 85 的课程,结果包含课程名和平均成绩,并按平均成绩从高到低排序。
要求:
- 写出自然语言问题并调用
text_to_sql; - 检查模型是否正确连接
courses与enrollments; - 使用
GROUP BY和HAVING,不要把分组条件误写为普通WHERE; - 对照手写查询,核对数值、别名和排序。
| SQL | |
|---|---|
7. 小结¶
Text-to-SQL 的质量依赖准确的模式说明、明确的自然语言问题和执行后的结果检查。对于查询改写,应比较结果语义而不只是 SQL 文本;对于模型生成的查询,应在权限受限的环境中运行,并设置实际的数据库安全和资源边界。