46 lines
2 KiB
Python
46 lines
2 KiB
Python
"""Migrationen passen zu den Modellen, auf SQLite und PostgreSQL (→ KONZEPT.md 18)."""
|
|
|
|
import hashlib
|
|
|
|
from alembic.autogenerate import compare_metadata
|
|
from alembic.script import ScriptDirectory
|
|
from alembic.runtime.migration import MigrationContext
|
|
from sqlalchemy import create_engine
|
|
|
|
from hugin_app.migration import FOLDER, VERSION_TABLE, migrate
|
|
from hugin_app.store.models import Base
|
|
|
|
|
|
def test_migrations_match_models(database_url):
|
|
migrate(database_url)
|
|
engine = create_engine(database_url)
|
|
try:
|
|
with engine.connect() as connection:
|
|
context = MigrationContext.configure(connection, opts={"version_table": VERSION_TABLE})
|
|
differences = [u for u in compare_metadata(context, Base.metadata)
|
|
if not (isinstance(u, tuple) and u[0] == "remove_table" and u[1].name == VERSION_TABLE)]
|
|
finally:
|
|
engine.dispose()
|
|
assert differences == [], "Modelle geändert ohne Migration: uv run alembic revision --autogenerate …"
|
|
|
|
|
|
# Ausgelieferte Migrationen bleiben, wie sie sind: Datenbanken kennen ihre Revision. Eine
|
|
# geänderte oder ersetzte Migration lässt bestehende Datenbanken nicht mehr migrieren
|
|
# („Can't locate revision“). Änderungen am Schema nur als neue Migration; neue Dateien hier
|
|
# mit Prüfsumme eintragen, sobald sie ausgeliefert sind.
|
|
RELEASED = {
|
|
"0001_initial_tables.py": "ff511bb66729de1998602be87a1714b37d20dff58265542c9bbce11b5fbacbde",
|
|
}
|
|
|
|
|
|
def test_released_migrations_unchanged():
|
|
for name, digest in RELEASED.items():
|
|
path = FOLDER / "versions" / name
|
|
assert path.exists(), f"{name} fehlt: ausgelieferte Migrationen nie löschen oder umbenennen"
|
|
assert hashlib.sha256(path.read_bytes()).hexdigest() == digest, (
|
|
f"{name} wurde geändert: ausgelieferte Migrationen nie ändern, sondern eine neue anlegen")
|
|
|
|
|
|
def test_migrations_form_one_chain():
|
|
scripts = ScriptDirectory(str(FOLDER))
|
|
assert len(scripts.get_heads()) == 1, f"mehrere Enden: {scripts.get_heads()}; mit alembic merge zusammenführen"
|