将SQLite结果列映射回其源 `表.列`

Simon Willison's Blog 工具

摘要

本研究探索了在任意SQLite查询中,确定每个结果列的源表和源列的方法,通过使用SQLite内部列元数据API(通过Python的apsw库或ctypes桥接访问),并应用于Datasette等工具。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/06/14 07:34

# 研究:将 SQLite 查询结果列映射回源 `table.column` 来源:https://simonwillison.net/2026/Jun/13/sqlite-column-provenance/ 研究(https://simonwillison.net/elsewhere/research/) 映射 SQLite 查询结果列回源 `table.column`(https://github.com/simonw/research/tree/main/sqlite-column-provenance#readme) —— 对于任意 SQLite 查询,确定每个结果列对应的源 `table.column` 是可行的,因为 SQLite 内部会计算该信息,并在编译时启用了 `SQLITE_ENABLE_COLUMN_METADATA` 的情况下,通过其列元数据 API 暴露出来。虽然 Python 标准库的 `sqlite3` 模块不直接提供此信息,但存在稳健的方法:使用第三方库 `apsw` 可通过 `cursor.description_full` 直接访问,或者通过纯标准库的 ctypes 桥接(`column_provenance.py`)来检索…… 如果能让 Datasette(https://datasette.io/)中的任意 SQL 查询根据结果中包含了来自哪些表的哪些列来呈现额外信息,那将非常巧妙。 要实现这一点,我们需要能够分析类似 `select users.name, orders.total from users join orders on orders.user_id = users.id` 这样的 SQL 查询,并以编程方式识别每个结果列的 `table.column` —— 不仅处理 JOIN,还要处理更复杂的语法如 CTE。 我决定让 Claude Code(Opus 4.8,因为 Fable 目前被美国政府禁止 https://simonwillison.net/2026/Jun/13/us-government-directive-to-suspend-access/)来解决这个问题。它找到了几个可行的方案——一个使用 apsw(https://github.com/rogerbinns/apsw),另一个使用 `ctypes` 调用 SQLite 的 `sqlite3_column_table_name()` C 函数(https://sqlite.org/c3ref/column_database_name.html)(该函数在 Python 中没有其他暴露方式),还有一个是通过巧妙分析 `EXPLAIN` 的输出得到。

相似文章

检测 SQLite 中的全表扫描

Lobsters Hottest

本文展示了如何利用 SQLite 的语句统计 API 检测全表扫描,并建议将其集成到 Rails 中,以便在测试/开发环境中发出警告或报错。

SQLite查询结果格式化演示

Simon Willison's Blog

基于WebAssembly的交互式演示,允许用户以20多种样式格式化SQL查询结果,包括表格、CSV、JSON、HTML和Markdown,并支持实时调整。

SQLite 查询解释器

Simon Willison's Blog

一个基于浏览器的工具,可对 SQLite 运行 SQL 查询,并以通俗易懂的英文解释查询计划和字节码输出。

用细齿梳检查 SQLite

Lobsters Hottest

John Regehr 描述了使用 tis-interpreter 在 SQLite 中搜索未定义行为,发现了其他工具遗漏的错误,如悬空指针使用和未初始化读取。