200 行 Text2SQL 原型离可上线,还差哪些证据
把DDL放进提示词、调用模型、再执行SQL,确实能做出一个可运行原型。麻烦在于“运行过”只回答了最窄的问题:某次输入没有报错。它没有回答访问范围、资源占用、答案口径,以及该拒绝时是否拒绝。
10月15日的PremiseSQL预印本研究了错误前提下的Text2SQL:一个问题可能假设了不存在的实体、缺少必要信息,模型仍会生成可执行SQL。论文的基准结论不能直接变成企业准确率,但这个问题值得放进原型验收。
概念示意图,非控制台截图、跑分或真实事件记录。
把模型出口当作不可信输入
下面只演示SQLite执行边界,不调用模型。它创建临时合成数据库,重新以只读方式打开,仅允许读取orders表的id、amount两列。授权回调默认拒绝其余动作,进度回调限制虚拟机执行工作量,结果最多取三行。
import sqlite3 from pathlib import Path from tempfile import TemporaryDirectory with TemporaryDirectory() as folder: path = Path(folder) / "demo.db" con = sqlite3.connect(path) con.execute("CREATE TABLE orders(id INTEGER, amount INTEGER)") con.executemany("INSERT INTO orders VALUES(?,?)", [(1,120),(2,80)]) con.commit() con.close() db = sqlite3.connect(path.as_uri() + "?mode=ro", uri=True) def authorize(action, table, column, database, trigger): if action == sqlite3.SQLITE_SELECT: return sqlite3.SQLITE_OK if action == sqlite3.SQLITE_READ and table == "orders": if column in {"id", "amount"}: return sqlite3.SQLITE_OK return sqlite3.SQLITE_DENY db.set_authorizer(authorize) ticks = [0] def progress(): ticks[0] += 1 return ticks[0] > 100 db.set_progress_handler(progress, 1000) assert db.execute("SELECT id,amount FROM orders ORDER BY id").fetchmany(3) == [(1,120),(2,80)] denied = 0 for sql in ("DELETE FROM orders", "ATTACH DATABASE ':memory:' AS other"): try: db.execute(sql) except sqlite3.DatabaseError: denied += 1 assert denied == 2 assert db.execute("SELECT id FROM orders").fetchall() == [(1,),(2,)] db.close() print("PASS read allowed; DELETE/ATTACH denied; rows preserved")SQLite官方文档说明,authorizer在语句准备过程中按操作被调用。图里的“准备、授权、执行”是逻辑职责区分,回调实际上嵌在prepare阶段,不是等整条SQL编译完后另做一次安全扫描。
这个例子刻意没有承诺什么
它没有实现通用SQL服务。CTE、聚合函数和其他表都未在许可集合里;这会拒绝一部分本来可以安全执行的查询。默认拒绝的代价要写出来,不能偷偷放宽后仍称“绝对安全”。
进度回调按SQLite虚拟机工作量触发,不是严格墙钟超时。fetchmany只限制本次取出的行数,不等价于优化器只处理这么多行。生产服务还需要在独立进程、连接和系统资源层设置预算,处理客户端取消后的清理。
SQLGlot可以检查语法和遍历AST,但它是解析、转译工具,不是数据库授权系统。一个SELECT仍可能读取越权列、调用有副作用的扩展函数,或者做高成本计算。
长上下文要怎样验收
把相同题目分别交给全量Schema与裁剪Schema,记录漏表、错误关联、重试与拒答。裁剪可能省输入,也可能剪掉必要关联;更长窗口可能保留元数据,也可能淹没关键注释。两种方案都该有失败例,而不是先选一个口号。
本地已运行上面的完整合成示例;SQLite授权与只读打开通过检查。未调用任何模型,也未验证MySQL/ClickHouse策略,不给准确率或并发能力结论。原型真正有价值的产物,是一份能说明“允许什么、拒绝什么、还有什么不知道”的接口契约。
本文的本地检查仅覆盖明确列出的合成示例;外部研究与产品文档不作为本人性能实测。
复现命令:将Python块保存为 readonly_demo.py,运行 python3 readonly_demo.py。核验环境:Python 3.9.6、SQLite 3.54.0、macOS arm64。