fix(migrations): schema base 000 per DB vuoti, stamp head dopo create_all (#6)

upgrade head partiva dalla 001, che sa solo aggiungere colonne a tabelle
che assume gia' esistenti: su un DB davvero vuoto falliva subito. Nuova
000_base_schema.py (revision "000_base", down_revision None) crea lo
schema pre-001 esplicitamente (create_table, non Base.metadata.create_all,
che porterebbe gia' le colonne di 001-013 e farebbe fallire 001 su
"Duplicate column"). No-op se la tabella recipes esiste gia'
(sa.inspect(bind).has_table("recipes")). 001 ora ha down_revision =
"000_base".

setup.py: init-db e reset-db, dopo create_all/drop_all+create_all,
eseguono l'equivalente di "alembic stamp head" (nuovo _stamp_head(),
command.stamp con la config di src/backend/migrations/alembic.ini) cosi'
un DB nato da create_all non ritenta le migrazioni 001-013 al prossimo
deploy.

Test: catena upgrade head su SQLite vuoto, tabelle/colonne confrontate
con Base.metadata; DB con recipes gia' nello stato pre-001 -> upgrade
head non fallisce (000 no-op). _stamp_head si appoggia a
migrations/env.py, che costruisce una connessione propria da
settings.database_url (non modificabile dai test tramite l'engine
patchato di setup.py): nei test di setup.py e' quindi no-op via
monkeypatch, cosi' init-db/reset-db continuano a girare su SQLite senza
toccare un MySQL vero.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-21 22:49:38 +02:00
parent 805f41c757
commit e20299548f
6 changed files with 388 additions and 2 deletions
+3
View File
@@ -34,6 +34,9 @@ def enable_setup(monkeypatch):
import src.backend.api.routers.setup as setup_mod
monkeypatch.setattr(setup_mod, "engine", test_engine)
monkeypatch.setattr(setup_mod, "async_session_factory", TestSessionFactory)
# See test_setup.py: _stamp_head would otherwise try to reach a real
# MySQL server via migrations/env.py.
monkeypatch.setattr(setup_mod, "_stamp_head", lambda: None)
async def _seed(client: AsyncClient) -> dict: