Simon Willison Ships alchemy-utils Alpha

Simon Willison’s alchemy-utils 0.1a0 is an alpha Python library and CLI release for using sqlite-utils-style table operations across multiple database engines. What would a database-agnostic version of his sqlite-utils project look like if it were backed by SQLAlchemy? The useful part is not just the package; it is the shape of the AI-built research spike that produced it. alchemy-utils is a Python library and command-line tool that tries to expose familiar insert, upsert, create, update, and introspection methods on top of SQLAlchemy-backed databases.
As of the August 12, 2026 post, Willison says he tasked OpenAI’s Codex and GPT-5.6 Sol Ultra with building the prototype, using his existing sqlite-utils repository as reference material. That makes the release interesting to anyone doing agentic coding, because it shows a small but real example of an AI coding workflow ending in a publishable alpha instead of a half-finished demo.
Read the release as a working receipt
The first thing to notice is how concrete the target was. Willison did not ask for “a database library.” He asked for the same core API as sqlite-utils, with specific methods called out: insert, upsert, insert_all, upsert_all, create, update, and table introspection.
That matters because coding agents are much better when the work has edges. “Make sqlite-utils, but SQLAlchemy-backed, tested against PostgreSQL, SQLite, and DuckDB” gives the agent a map, a reference implementation, and a compatibility check.
Don't treat the alpha as proof that the broad problem is solved. It is better to read alchemy-utils 0.1a0 as a receipt: a bounded project, a reference repo, a database matrix, tests, and a release marker.
Willison’s example CLI command is refreshingly mundane:
uvx --with 'alchemy-utils[postgresql]' alchemy-utils rows \
'postgresql+psycopg://simon@localhost:5432/simonwillisonblog' \
redirects_redirect
That one-liner lists rows from a local PostgreSQL table. Small examples like this are valuable because they force the project to cross the line from “library code exists” to “a developer can run it.”
The prompt had product taste baked in
The most interesting part of the source note is the assignment. It included the package manager (uv init), the development style (“red/green TDD and pytest”), the test targets, and the habit of committing early and often.
That is product taste, not just prompting. It tells the coding agent what finished work should feel like: initialized project, visible history, executable tests, compatibility with real engines, and an API shaped by an existing successful tool.
Watch for copying the exact prompt without copying the constraints. If your repo has no reference implementation, no test harness, and no acceptance examples, “do a research spike” becomes a permission slip for wandering.
A closer Claude Code version of the same move would be a slash command that starts with the contract, not the implementation:
/agent-spike-db-utils
Goal: prototype a small SQLAlchemy-backed utility with sqlite-utils-like table APIs.
- Read ./vendor/sqlite-utils-notes.md for API shape.
- Preserve method names where practical.
Acceptance checks:
- pytest passes locally.
- Tests cover SQLite and one networked database if available.
- CLI can list rows from a real table.
- Commit after each passing slice.
Stop conditions:
- Do not add migrations, auth, background jobs, or web UI.
- Do not hide database-specific behavior behind fake portability.
That command is not magic. It is just a tidy boundary around the work.
Database portability is where the hard parts live
SQLAlchemy, the Python SQL toolkit and ORM is a sensible foundation for this kind of experiment because it already knows how to talk to many engines. But a shared API does not erase database differences.
The hard parts are usually the boring ones: conflict handling, type reflection, default values, transaction behavior, identifier quoting, JSON support, and what “upsert” means across engines. PostgreSQL, SQLite, and DuckDB overlap a lot, but they are not the same database wearing different hats.
That is why the test matrix matters. If a coding agent writes a beautiful abstraction that only runs on SQLite, it has not built a database-agnostic library. It has built a SQLite library with optimistic naming.
Don't accept a green unit test suite that mocks away the database. For a tool like this, at least one test should touch each promised engine, even if the first alpha only supports a narrow slice.
Borrow the spike shape, not the hype
The practical takeaway is simple: use alchemy-utils 0.1a0 as a pattern for bounded AI coding experiments. Pick one real library-shaped problem, name the methods, name the test matrix, and require a runnable command before you call it done.
This fits neatly beside AI coding governance, but it should not be turned into a ceremony. The lesson is smaller and better: a coding agent can move quickly when the task has a reference implementation, a test harness, and a visible release threshold.
Don't ask for production confidence from an alpha spike. An alpha can prove direction, API taste, and test feasibility. It cannot prove long-term maintenance, edge-case correctness, or compatibility with every database dialect your users will bring.
If you want a nearby comparison in a different technical domain, Discovered Materials Uses Agents for Chip Heat is another example of agents being useful when the work is boxed into a measurable experiment.
Copy this small spike receipt
Use this when you want a coding agent to build a prototype that can be reviewed without replaying the whole chat.
AI coding spike receipt
Project:
- Name:
- One-sentence goal:
- Existing project or API to imitate:
Boundaries:
- Must include:
- Must not include:
- Known unsupported cases:
Execution:
- Package/init command:
- Test command:
- Minimum runnable CLI or script:
- Commit rule:
Compatibility:
- Runtime versions:
- External services required:
- Database, browser, or API targets:
Review evidence:
- Passing tests:
- Example command output:
- Files changed:
- Follow-up risks:
For a Claude Code repo, keep this as a slash-command template rather than permanent repository memory. If the rule is specific to one spike, it belongs in the command or task prompt; if it is a durable repo constraint, then a short note in CLAUDE.md can make sense.
Watch the next alpha
Try the package only on a disposable database or local copy, then read the tests before trusting the abstraction. The next useful signal will be how many database-specific edge cases become explicit instead of hidden.
Further reading
Where to go next
Start from AI coding governance.