From 0022986d4e1b6a64e2b53f52fb7b8426ffdf79b3 Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Wed, 28 Jan 2026 01:52:33 +0000 Subject: [PATCH] Implement migration to remove created_at timestamp from Orgs that already has one, bumping db v1. --- paskia/db/jsonl.py | 10 ++++++++++ paskia/db/migrations.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 paskia/db/migrations.py diff --git a/paskia/db/jsonl.py b/paskia/db/jsonl.py index 0cdf456..4490cac 100644 --- a/paskia/db/jsonl.py +++ b/paskia/db/jsonl.py @@ -18,6 +18,7 @@ import aiofiles import jsondiff import msgspec +from paskia.db.migrations import apply_migrations from paskia.db.structs import DB, SessionContext _logger = logging.getLogger(__name__) @@ -172,10 +173,19 @@ class JsonlStore: try: data_dict = await load_jsonl(self.db_path) if data_dict: + # Apply schema migrations + migrated = apply_migrations(data_dict) + decoder = msgspec.json.Decoder(DB) self.db = decoder.decode(msgspec.json.encode(data_dict)) self.db._store = self self._previous_builtins = data_dict + + # Persist migration + if migrated: + with self.transaction("migrate"): + pass # Trigger change detection + await self.flush() except ValueError: if self.db_path.exists(): raise diff --git a/paskia/db/migrations.py b/paskia/db/migrations.py new file mode 100644 index 0000000..eabbf47 --- /dev/null +++ b/paskia/db/migrations.py @@ -0,0 +1,34 @@ +""" +Database schema migrations. + +Migrations are applied during database load based on the version field. +Each migration should be idempotent and only run when needed. +""" + +import logging + +_logger = logging.getLogger(__name__) + + +def apply_migrations(data_dict: dict) -> bool: + """Apply any pending schema migrations to the database dictionary. + + Args: + data_dict: The raw database dictionary loaded from JSONL + + Returns: + True if any migrations were applied, False otherwise + """ + db_version = data_dict.get("v", 0) + migrated = False + + if db_version == 0: + # Migration v0 -> v1: Remove created_at from orgs (field removed from schema) + if "orgs" in data_dict: + for org_data in data_dict["orgs"].values(): + org_data.pop("created_at", None) + data_dict["v"] = 1 + migrated = True + _logger.info("Applied schema migration: v0 -> v1 (removed org.created_at)") + + return migrated