文本到 SQL 生成:自然语言查询数据库
FreeGuideOnline
最新
2026-06-23
bash pip install openai sqlite3
本示例使用 OpenAI API 调用大语言模型,数据库采用 SQLite。
### 第一步:设计样例数据库
创建一个包含三张表的简单电商数据库。
```sql
-- 文件:schema.sql
CREATE TABLE customers (
customer_id INTEGER PRIMARY KEY,
name TEXT,
city TEXT
);
CREATE TABLE products (
product_id INTEGER PRIMARY KEY,
product_name TEXT,
category TEXT,
price REAL
);
CREATE TABLE orders (
order_id INTEGER PRIMARY KEY,
customer_id INTEGER,
product_id INTEGER,
quantity INTEGER,
order_date DATE,
FOREIGN KEY(customer_id) REFERENCES customers(customer_id),
FOREIGN KEY(product_id) REFERENCES products(product_id)
);
插入少量测试数据:
INSERT INTO customers VALUES (1,'Alice','New York'),(2,'Bob','Los Angeles');
INSERT INTO products VALUES (1,'Laptop','Electronics',1200),(2,'Headphones','Electronics',150);
INSERT INTO orders VALUES (1,1,1,1,'2025-03-10'),(2,2,2,2,'2025-03-12');
第二步:构造大模型提示词
将数据库 schema 和用户问题组装,通过 few-shot 示例引导模型。
# text2sql.py
import openai
import sqlite3
openai.api_key = "your-api-key"
schema = """
表: customers
列: customer_id, name, city
表: products
列: product_id, product_name, category, price
表: orders
列: order_id, customer_id, product_id, quantity, order_date
外键: customer_id 引用 customers, product_id 引用 products
"""
def build_prompt(question):
prompt = f"""你是一个SQL查询生成助手。根据以下数据库结构,将用户问题转换为准确的SQL语句。
{schema}
示例:
问题: 列出所有客户姓名。
SQL: SELECT name FROM customers;
问题: 2025年3月10日之后的所有订单总数是多少?
SQL: SELECT COUNT(*) FROM orders WHERE order_date > '2025-03-10';
现在请转换:
问题: {question}
SQL: """
return prompt
def generate_sql(question):
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": build_prompt(question)}],
temperature=0
)
return response.choices[0].message.content.strip()
第三步:执行并呈现结果
def run_query(sql):
conn = sqlite3.connect("ecommerce.db")
cur = conn.cursor()
cur.execute(sql)
rows = cur.fetchall()
conn.close()
return rows
# 用户提问
user_question = "哪个客户买了最贵的产品?"
sql = generate_sql(user_question)
print(f"生成的SQL: {sql}")
# 安全起见,可增加简单的 SQL 执行检查,例如只允许 SELECT
if sql.strip().lower().startswith("select"):
results = run_query(sql)
print("查询结果:", results)
else:
print("非 SELECT 语句,已阻止执行")
可能的输出
生成的SQL: SELECT customers.name FROM customers
JOIN orders ON customers.customer_id = orders.customer_id
JOIN products ON orders.product_id = products.product_id
ORDER BY products.price DESC LIMIT 1;
查询结果: [('Alice',)]