File size: 1,530 Bytes
4b09d2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
"""Additive SQLite auto-migration: an old-schema DB gains new ORM columns
at startup instead of 500ing (the 'no such column: projects.archived' bug)."""

import sqlite3

from sqlalchemy import create_engine, inspect

from app.db import Base, auto_migrate_sqlite
from app.models import Project  # noqa: F401 - registers tables on Base.metadata


def test_old_schema_gains_missing_columns(tmp_path):
    db_path = tmp_path / "old.db"

    # Simulate a dev DB created before archived/language/etc. existed.
    conn = sqlite3.connect(db_path)
    conn.execute(
        "CREATE TABLE projects (id VARCHAR(32) PRIMARY KEY, name VARCHAR(200), "
        "description TEXT, created_at VARCHAR(32))"
    )
    conn.execute(
        "INSERT INTO projects VALUES ('abc123', 'Old Project', '', '2026-07-01T00:00:00')"
    )
    conn.commit()
    conn.close()

    engine = create_engine(f"sqlite:///{db_path}")
    Base.metadata.create_all(engine)  # creates the other, brand-new tables
    added = auto_migrate_sqlite(engine, Base.metadata)

    assert "projects.archived" in added
    cols = {c["name"] for c in inspect(engine).get_columns("projects")}
    assert "archived" in cols

    # Existing row survives with the default applied, and queries work.
    conn = sqlite3.connect(db_path)
    row = conn.execute("SELECT name, archived FROM projects WHERE id='abc123'").fetchone()
    conn.close()
    assert row == ("Old Project", 0)

    # Second run is a no-op (idempotent).
    assert auto_migrate_sqlite(engine, Base.metadata) == []