| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- """spool_usage_history.spool_id becomes nullable, ON DELETE SET NULL, on existing SQLite databases.
- Deleting a spool must keep its usage (the costs its prints are recalculated
- from), so the column has to take NULL on tables made before. (PostgreSQL is
- checked by scripts/check_postgres_upgrade.py.)
- """
- import pytest
- from sqlalchemy import text
- from sqlalchemy.ext.asyncio import create_async_engine
- from backend.app.core import database
- # As create_all made the table from the old model ...
- CREATED_BY_THE_MODEL = """
- CREATE TABLE spool_usage_history (
- \tid INTEGER NOT NULL,
- \tspool_id INTEGER NOT NULL,
- \tprinter_id INTEGER,
- \tprint_name VARCHAR(500),
- \tarchive_id INTEGER,
- \tweight_used FLOAT NOT NULL,
- \tPRIMARY KEY (id),
- \tFOREIGN KEY(spool_id) REFERENCES spool (id) ON DELETE CASCADE,
- \tFOREIGN KEY(printer_id) REFERENCES printers (id) ON DELETE SET NULL,
- \tFOREIGN KEY(archive_id) REFERENCES print_archives (id) ON DELETE SET NULL
- )
- """
- # ... and as the usage-history migration's own CREATE TABLE made it.
- CREATED_BY_THE_MIGRATION = """
- CREATE TABLE spool_usage_history (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- spool_id INTEGER NOT NULL REFERENCES spool(id) ON DELETE CASCADE,
- printer_id INTEGER REFERENCES printers(id) ON DELETE SET NULL,
- print_name VARCHAR(500),
- weight_used REAL NOT NULL DEFAULT 0
- )
- """
- @pytest.fixture(autouse=True)
- def sqlite_dialect(monkeypatch):
- monkeypatch.setattr(database, "is_sqlite", lambda: True)
- @pytest.mark.asyncio
- @pytest.mark.parametrize("legacy", [CREATED_BY_THE_MODEL, CREATED_BY_THE_MIGRATION], ids=["model", "migration"])
- async def test_the_spool_column_takes_null_and_says_set_null(legacy):
- engine = create_async_engine("sqlite+aiosqlite:///:memory:")
- try:
- async with engine.begin() as conn:
- await conn.execute(text(legacy))
- await conn.execute(text("INSERT INTO spool_usage_history (id, spool_id, weight_used) VALUES (1, 7, 5)"))
- await database._migrate_spool_usage_outlives_its_spool(conn)
- await database._migrate_spool_usage_outlives_its_spool(conn) # a restart changes nothing
- await conn.execute(text("UPDATE spool_usage_history SET spool_id = NULL WHERE id = 1"))
- assert (await conn.execute(text("SELECT spool_id, weight_used FROM spool_usage_history"))).one() == (
- None,
- 5,
- )
- sql = (
- await conn.execute(text("SELECT sql FROM sqlite_master WHERE name = 'spool_usage_history'"))
- ).scalar_one()
- assert "CASCADE" not in sql
- # Only the spool column changed.
- assert "weight_used" in sql and "NOT NULL" in sql.split("weight_used", 1)[1].split(",", 1)[0]
- finally:
- await engine.dispose()
|