SQLite-utils now ships with proper schema migrations
Simon Willison's sqlite-utils 4.0 adds schema migration tracking. The library that made it trivial to load data into SQLite now makes it trivial to evolve those tables.
Simon Willison dropped sqlite-utils 4.0 today with a feature I did not know I needed: proper schema migration tracking.
The library already made it dead simple to shove JSON or CSV into a SQLite database with one Python function call. But once you had data in there, changing the schema meant writing raw ALTER TABLE statements or deleting the database and starting over.
Now you get a migrations system that tracks what has run. Define schema changes in Python, apply them with db.migrate(), and sqlite-utils writes a changelog to a _migrations table. Rollback support is there too.
This matters because SQLite is how most data projects start. You scrape something, throw it in a database, query it locally. Then the schema changes because the source added a field or you realised you need an index. Without migration tracking, you either keep a shell script of ALTER statements or you nuke the database and re-import.
The timing is interesting. Willison has been pushing SQLite as a deployment target for years, not just a dev tool. Datasette runs on SQLite in production. If you are treating SQLite as a real database, you need real migrations.
I have used sqlite-utils for prototyping detection pipelines at Nagarro. Load event logs, run queries, tune the logic. But I always hit the schema problem when the log format changed. This would have saved the re-import loop.
The Python API looks clean. You write functions that take a database object and call add_column() or create_index(). No string concatenation. No migration file DSL to learn. Just Python.
Migrations were the missing piece. Now sqlite-utils is not just for loading data. It is for keeping that data schema under version control.
Source: SQLite-utils 4.0, now with database schema migrations