Add support for migrations

This commit is contained in:
Šarūnas Nejus 2026-02-08 07:09:01 +00:00
parent 0048779aeb
commit a1bed02a58
No known key found for this signature in database

View file

@ -26,14 +26,7 @@ import threading
import time
from abc import ABC
from collections import defaultdict
from collections.abc import (
Callable,
Generator,
Iterable,
Iterator,
Mapping,
Sequence,
)
from collections.abc import Mapping
from functools import cached_property
from sqlite3 import Connection, sqlite_version_info
from typing import TYPE_CHECKING, Any, AnyStr, ClassVar, Generic, NamedTuple
@ -1088,11 +1081,14 @@ class Database:
self._db_lock = threading.Lock()
# Set up database schema.
self._ensure_migration_state_table()
for model_cls in self._models:
self._make_table(model_cls._table, model_cls._fields)
self._make_attribute_table(model_cls._flex_table)
self._create_indices(model_cls._table, model_cls._indices)
self._migrate()
# Primitive access control: connections and transactions.
def _connection(self) -> Connection:
@ -1292,6 +1288,38 @@ class Database:
f"ON {table} ({', '.join(index.columns)});"
)
# Generic migration state handling.
def _ensure_migration_state_table(self) -> None:
with self.transaction() as tx:
tx.script("""
CREATE TABLE IF NOT EXISTS migration_state (
name TEXT PRIMARY KEY,
done INTEGER NOT NULL DEFAULT 0
);
""")
def _migrate(self) -> None:
"""Perform any necessary migration for the database."""
def get_migration_state(self, name: str) -> bool:
"""Return whether a named migration has been marked complete."""
with self.transaction() as tx:
rows = tx.query(
"SELECT done FROM migration_state WHERE name = ?",
(name,),
)
return bool(rows and rows[0]["done"])
def set_migration_state(self, name: str, done: bool) -> None:
"""Set completion state for a named migration."""
with self.transaction() as tx:
tx.mutate(
"INSERT INTO migration_state(name, done) VALUES (?, ?) "
"ON CONFLICT(name) DO UPDATE SET done = excluded.done",
(name, int(done)),
)
# Querying.
def _fetch(