将 SQLite 结果列追溯到源表列
Simon Willison··作者 Simon Willison
关键信息
这个问题比简单的列查找更难,因为连接、别名和 CTE 都会掩盖值的原始来源。文章提到,SQLite 在 C 层提供了 `sqlite3_column_table_name()`,但在 Python 中并不能直接使用,需要借助 `ctypes` 或其他封装。
资讯摘要
Simon Willison 的这篇研究文章探讨了 SQLite 是否能够告诉你,查询结果中的每一列分别来自哪个底层的 `table.column`。他把这项工作视为 Datasette 的一个潜在增强:让任意 SQL 查询结果都能附带来源信息。文中给出的动机示例是类似 `select users.name, orders.total from users join orders on orders.user_id = users.id` 的查询,这类场景需要把每个结果列可靠地映射回它的源列。难点在于,一旦查询使用了连接、别名和公共表表达式(CTE),原始来源就会变得不那么明显。
为了解这个问题,Willison 让 Claude Code 使用 Opus 4.8 来寻找方案。研究结果给出了三条有前景的路径:使用 APSW、通过 `ctypes` 调用 SQLite 的 `sqlite3_column_table_name()` C 函数,或者通过分析 `EXPLAIN` 输出来推断列的来源。文章的定位是探索性研究,而不是已经完成的实现,但它为 Python 工具中的查询内省提供了几条具体可行的方向。
资讯正文
<strong>研究:</strong> <a href="https://github.com/simonw/research/tree/main/sqlite-column-provenance#readme">将 SQLite 结果列映射回它们来源的 `table.column`</a>
如果 <a href="https://datasette.io/">Datasette</a> 中的任意 SQL 查询,能够根据结果里包含了哪些表的哪些列而呈现额外信息,那就很不错了。
要实现这一点,我们需要能够看着这样一条 SQL 查询:<code>select users.name, orders.total from users join orders on orders.user_id = users.id</code>,并以程序方式识别每个结果对应的 <code>table.column</code>——这不仅要处理 join,还要处理诸如 CTE 之类更复杂的语法。
我决定把这个问题交给 Claude Code(Opus 4.8,因为 Fable 目前已被<a href="https://simonwillison.net/2026/Jun/13/us-government-directive-to-suspend-access/">美国政府禁止</a>)来解决。它找到了几个有前景的方案——其中一个使用 <a href="https://github.com/rogerbinns/apsw">apsw</a>,另一个使用 <code>ctypes</code> 访问 SQLite 的 <code>sqlite3_column_table_name()</code> <a href="https://sqlite.org/c3ref/column_database_name.html">C 函数</a>(Python 本身并未以其他方式暴露该函数),还有一个则通过巧妙地解析 <code>EXPLAIN</code> 的输出来实现。
标签:<a href="https://simonwillison.net/tags/python">python</a>、<a href="https://simonwillison.net/tags/sqlite">sqlite</a>、<a href="https://simonwillison.net/tags/datasette">datasette</a>
来源与参考
收录于 2026-06-15