alchemy-utils 0.1a0:基于 SQLAlchemy 的跨数据库版 sqlite-utils
我一直在琢磨,如果把我那个 sqlite-utils Python 库和命令行工具做成数据库无关的版本,会是什么样子。今天早上(说真的就是洗澡时冒出的念头),我让 Codex 和 GPT-5.6 Sol Ultra 帮我搭了个原型:
做一次技术调研,看看要构建这样一个库需要什么:核心 API 跟 SQLite-utils 保持一致——尤其是 insert、upsert、insert_all、upsert_all 以及 create 和 update 这些方法,还有表结构自省的功能——但底层用 SQLAlchemy,这样就能支持多种数据库引擎
用 PostgreSQL、SQLite 和 DuckDB 做测试
参考 ~/dev/sqlite-utils
建一个 git 仓库,多多提交——用 uv init 初始化项目——采用红绿 TDD 流程加 pytest,PostgreSQL 的测试可以参考 ~/dev/django-sql-dashboard 的做法
只用了几次后续提示,项目就达到了可以作为 alpha 版发布的状态。
下面这行命令可以列出我本地博客数据库(PostgreSQL 版)中某张表的记录:
uvx --with 'alchemy-utils[postgresql]' alchemy-utils rows 'postgresql+psycopg://simon@localhost:5432/simonwillisonblog' redirects_redirect
输出开头是这样的:
[
{
"id": 2328,
"domain": "simonwillison.net",
"path": "2020/May/21/apple-photos-sqlite/",
"target": "/2020/May/21/dogsheep-photos/",
"created": "2020-05-21T13:03:46.591692-07:00"
},
{
"id": 3,
"domain": "feeds.simonwillison.net",
"path": "swn-links",
"target": "https://simonwillison.net/atom/links/",
"created": "2017-10-01T14:12:54.820729-07:00"
}
或者你也可以用一个 DuckDB 数据库,里面装旧金山所有的树木数据,表结构会自动根据文件来创建:
curl 'https://raw.githubusercontent.com/simonw/sf-tree-history/refs/heads/main/Street_Tree_List.csv' | uvx --with 'alchemy-utils[duckdb]' alchemy-utils insert 'duckdb:////tmp/trees.db' trees - --csv
(这条命令我第一次跑的时候花了将近一个小时,所以我让 Codex 优化了一下,缩短到了大约 35 秒。)