Skip to main content

csrd-migration

Versioned, idempotent schema migrations for csrd.repository database adapters.

Quick start

from csrd.migration import Migration, MigrationRunner
from csrd.repository import SQLiteAdapter

MIGRATIONS = [
    Migration(
        version="001",
        description="create users table",
        up="CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT NOT NULL)",
        down="DROP TABLE users",
    ),
]

async def setup_db():
    adapter = SQLiteAdapter("app.db")
    await adapter.connect()
    runner = MigrationRunner()
    await runner.apply_all(adapter, MIGRATIONS)

API

Migration

Frozen dataclass representing a single schema change.

Field Type Description
version str Unique version identifier (e.g. "001", "002")
description str Human-readable description
up str | Sequence[str] SQL to apply the migration
down str | Sequence[str] SQL to revert the migration

A str is split into statements by split_sql (below). A list or tuple is executed verbatim, one element per statement — use it when you want full control (lists are stored as tuples, so the dataclass stays hashable). up_statements() / down_statements() return exactly what the runner executes.

split_sql(sql, *, nested_comments=True) -> list[str]

Splits at top-level semicolons only. A ; does not end a statement inside:

  • single-quoted strings ('it''s; ok') and E'...' strings (E'it\'s; ok');
  • double-quoted identifiers and MySQL backtick identifiers;
  • dollar quoting: $$ ... $$ and $tag$ ... $tag$ (PostgreSQL function / DO bodies);
  • -- line comments and /* */ block comments (nested, PostgreSQL-style; pass nested_comments=False for first-*/-wins);
  • the BEGIN ... END body of a CREATE TRIGGER / FUNCTION / PROCEDURE statement — SQLite triggers, PostgreSQL BEGIN ATOMIC, MySQL procedures (CASE ... END, END IF, END LOOP, END WHILE, END REPEAT, END CASE handled).

Statements that are empty or comment-only are dropped; each statement is stripped and has no trailing ;.

Migration(
    version="007",
    description="remove shares when a collection is deleted",
    up="""
        CREATE FUNCTION remove_shares() RETURNS trigger AS $$
        BEGIN
            DELETE FROM shares WHERE collection_id = OLD.id;
            RETURN OLD;
        END
        $$ LANGUAGE plpgsql;
        CREATE TRIGGER collections_remove_shares AFTER DELETE ON collections
            FOR EACH ROW EXECUTE FUNCTION remove_shares();
    """,
    down="DROP TRIGGER collections_remove_shares ON collections; DROP FUNCTION remove_shares();",
)

Statements run without bind parameters, so PGAdapter / MariaAdapter send them verbatim — a literal % (RAISE NOTICE '%', format('%I')) or :word needs no escaping.

MigrationRunner

Applies and tracks migrations against any ABCDatabaseAdapter.

Method Description
apply_all(adapter, migrations) Apply all pending migrations in order
rollback(adapter, migrations, *, to_version=None) Roll back applied migrations in reverse order. Pass to_version to stop at a specific version, or None to roll back all
reapply_all(adapter, migrations) Roll back all then re-apply — clean schema reset without dropping the database
current_version(adapter) Return the latest applied version, or None
pending(adapter, migrations) Return migrations not yet applied

The runner creates a _csrd_migrations table automatically to track applied versions. Re-running is idempotent — already-applied migrations are skipped.

Design

  • Adapter-agnostic — works with SQLiteAdapter, PGAdapter, MariaAdapter
  • Idempotent — safe to call on every startup
  • Ordered — migrations are applied in list order
  • Future-ready — the Migration dataclass is the stable interface for a future model→SQL translation layer (see docs/AUGMENT_PLAN.md)

Metadata

Release files for csrd-migration 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for csrd-migration 0.8.0
File Size Uploaded
csrd_migration-0.8.0.tar.gz 12.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for csrd-migration 0.8.0
File Interpreter ABI Platform
csrd_migration-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 21.9 kB

Release files / csrd_migration-0.8.0.tar.gz

Download URL csrd_migration-0.8.0.tar.gz
Size 12.9 kB
Tags Source
SHA-256 checksum
How to use checksums
fefcd410bd350289a9be2d1da874b1578461354a6df5c1bba2af7f14e0619669
BLAKE2b-256 checksum
How to use checksums
b740beb8a372716a70720936bc3cf4324e502b262dec9ea8c50da364b8c4c853
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release files / csrd_migration-0.8.0-py3-none-any.whl

Download URL csrd_migration-0.8.0-py3-none-any.whl
Size 9.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
37a47e57f080ac4458cf6cc1be011d067ceead44df5d77f5dae1322bdcbcee0b
BLAKE2b-256 checksum
How to use checksums
810680cda4185663a298a5257aac4ac7f3da9020c7d27c226001cb11b2e9e241
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.8.0 This release

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.30

2 release files

0.5.29

2 release files

0.5.28

2 release files

0.5.27

2 release files

0.5.26

2 release files

0.5.25

2 release files

0.5.24

2 release files

0.5.23

2 release files

0.5.22

2 release files

0.5.21

2 release files

0.5.9

2 release files

0.5.8

2 release files

0.5.7

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page