mirror of
https://github.com/jbranchaud/til
synced 2026-09-02 09:41:47 +00:00
Add Manage Lightweight Schema Migrations With User Version as a SQLite TIL
This commit is contained in:
@@ -10,7 +10,7 @@ working across different projects via [VisualMode](https://www.visualmode.dev/).
|
|||||||
|
|
||||||
For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter).
|
For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter).
|
||||||
|
|
||||||
_1849 TILs and counting..._
|
_1850 TILs and counting..._
|
||||||
|
|
||||||
See some of the other learning resources I work on:
|
See some of the other learning resources I work on:
|
||||||
|
|
||||||
@@ -1634,6 +1634,7 @@ If you've learned something here, support my efforts writing daily TILs by
|
|||||||
|
|
||||||
- [Display Results In Readable Column Format](sqlite/display-results-in-readable-column-format.md)
|
- [Display Results In Readable Column Format](sqlite/display-results-in-readable-column-format.md)
|
||||||
- [Explore The Database Schema](sqlite/explore-the-database-schema.md)
|
- [Explore The Database Schema](sqlite/explore-the-database-schema.md)
|
||||||
|
- [Manage Lightweight Schema Migrations With `user_version`](sqlite/manage-lightweight-schema-migrations-with-user-version.md)
|
||||||
|
|
||||||
### Streaming
|
### Streaming
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# Manage Lightweight Schema Migrations With `user_version`
|
||||||
|
|
||||||
|
The [`user_version` pragma](https://sqlite.org/pragma.html#pragma_user_version)
|
||||||
|
in SQLite is a bit of persistent state built into the header of a SQLite
|
||||||
|
database file.
|
||||||
|
|
||||||
|
> The user_version pragma will get or set the value of the user-version integer
|
||||||
|
> at offset 60 in the database header. The user-version is an integer that is
|
||||||
|
> available to applications to use however they want. SQLite makes no use of the
|
||||||
|
> user-version itself.
|
||||||
|
|
||||||
|
One use case for `user_version` is as a schema version indicator. It starts at
|
||||||
|
`0` which can mean nothing has been migrated yet.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
sqlite> pragma user_version;
|
||||||
|
0
|
||||||
|
```
|
||||||
|
|
||||||
|
Then for each individual migration that my application applies, I can increment
|
||||||
|
the value of `user_version`. At any point in the application lifecycle, it knows
|
||||||
|
up to what point schema migrations have been run. If the number of migrations is
|
||||||
|
greater than the value of `user_version`, then migrations need to be applied.
|
||||||
|
|
||||||
|
Here is some Python code (from
|
||||||
|
[`py-vmt`](https://github.com/jbranchaud/py-vmt/blob/e426b3fda92f59c116494a4a4ed992965bac1dba/src/py_vmt/db.py))
|
||||||
|
that uses this pattern:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from sqlite3 import Connection
|
||||||
|
|
||||||
|
MIGRATIONS = [
|
||||||
|
# ...
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# Using the `user_version` pragma in SQLite, this checks if there are any
|
||||||
|
# sets of statements in `MIGRATIONS` that have not been run yet. It then
|
||||||
|
# executes those and updates `user_version`.
|
||||||
|
def migrate(conn: Connection):
|
||||||
|
version = conn.execute("pragma user_version").fetchone()[0]
|
||||||
|
for i, statement in enumerate(MIGRATIONS[version:], start=version):
|
||||||
|
conn.executescript(statement)
|
||||||
|
conn.execute(f"pragma user_version = {i + 1}")
|
||||||
|
conn.commit()
|
||||||
|
```
|
||||||
|
|
||||||
|
Notice that `user_version` can be updated directly with an assignment:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
sqlite> pragma user_version = 3;
|
||||||
|
sqlite> pragma user_version;
|
||||||
|
3
|
||||||
|
```
|
||||||
|
|
||||||
|
A `select` statement can also be used to access the `user_version` value like
|
||||||
|
so:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
sqlite> select * from pragma_user_version;
|
||||||
|
3
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user