diff --git a/finance/alembic/versions/e7f1a9c3b214_szenario_zeitraum.py b/finance/alembic/versions/e7f1a9c3b214_szenario_zeitraum.py index 5fcf507..65ecf71 100644 --- a/finance/alembic/versions/e7f1a9c3b214_szenario_zeitraum.py +++ b/finance/alembic/versions/e7f1a9c3b214_szenario_zeitraum.py @@ -23,10 +23,12 @@ def upgrade() -> None: # Bestandsdaten: percent/absolute/remove haben end_date NULL (API hat es # bisher genullt) und gelten damit unverändert unbegrenzt. op.add_column('scenario_modifiers', sa.Column('start_date', sa.Date(), nullable=True)) - op.add_column('scenario_planned_items', - sa.Column('category_id', sa.Integer(), nullable=True)) - op.create_foreign_key(FK_PLANNED_CATEGORY, 'scenario_planned_items', - 'categories', ['category_id'], ['id']) + # Batch-Modus: SQLite kennt kein ALTER von Constraints (Tabelle wird neu + # angelegt); auf Postgres entspricht das den direkten ALTER-Befehlen. + with op.batch_alter_table('scenario_planned_items') as batch: + batch.add_column(sa.Column('category_id', sa.Integer(), nullable=True)) + batch.create_foreign_key(FK_PLANNED_CATEGORY, 'categories', + ['category_id'], ['id']) op.create_table( 'scenario_recurring_items', sa.Column('id', sa.Integer(), primary_key=True), @@ -49,6 +51,6 @@ def downgrade() -> None: op.execute("UPDATE scenario_modifiers SET end_date = NULL WHERE kind <> 'ende'") op.drop_index('ix_scenario_recurring_items_scenario_id', 'scenario_recurring_items') op.drop_table('scenario_recurring_items') - op.drop_constraint(FK_PLANNED_CATEGORY, 'scenario_planned_items', type_='foreignkey') - op.drop_column('scenario_planned_items', 'category_id') + with op.batch_alter_table('scenario_planned_items') as batch: + batch.drop_column('category_id') op.drop_column('scenario_modifiers', 'start_date') diff --git a/finance/tests/test_migration_sqlite.py b/finance/tests/test_migration_sqlite.py new file mode 100644 index 0000000..b161bcf --- /dev/null +++ b/finance/tests/test_migration_sqlite.py @@ -0,0 +1,35 @@ +"""Alembic-Revision e7f1a9c3b214 (A14) muss auch auf SQLite hoch/runter/hoch laufen.""" +from pathlib import Path + +from alembic import command +from alembic.config import Config +from sqlalchemy import create_engine, inspect + +ROOT = Path(__file__).resolve().parent.parent + + +def test_migration_a14_sqlite_up_down_up(tmp_path, monkeypatch): + url = f"sqlite:///{tmp_path / 'mig.db'}" + monkeypatch.setenv("FB_DATABASE_URL", url) + from app.config import get_settings + get_settings.cache_clear() + try: + cfg = Config(str(ROOT / "alembic.ini")) + cfg.set_main_option("script_location", str(ROOT / "alembic")) + engine = create_engine(url) + + def state(): + insp = inspect(engine) + return ("scenario_recurring_items" in insp.get_table_names(), + "category_id" in {c["name"] for c in + insp.get_columns("scenario_planned_items")}) + + command.upgrade(cfg, "head") + assert state() == (True, True) + command.downgrade(cfg, "d5e8b3c7a410") + assert state() == (False, False) + command.upgrade(cfg, "head") + assert state() == (True, True) + engine.dispose() + finally: + get_settings.cache_clear()