feat: add SQLAlchemy declarative base, Alembic environment, and gitignore fix

Configures stable constraint naming so autogeneration produces clean diffs.
Alembic uses the sync psycopg driver while the runtime app uses asyncpg.

Also fixes a .gitignore bug caught during this task: the bare 'models/'
rule for the ML weights volume was matching backend/app/models/ (Python
package). Anchored all volume rules to repo root (/images/, /import/,
/downloads/, /models/, /postgres_data/, /redis_data/).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-14 07:32:58 -04:00
parent fe0a311d39
commit a03655039c
7 changed files with 150 additions and 7 deletions
+7
View File
@@ -0,0 +1,7 @@
"""All ORM models. Import this module to make every model visible to Alembic."""
from .base import Base
# Concrete models land in Task 6 and re-export here.
__all__ = ["Base"]
+17
View File
@@ -0,0 +1,17 @@
"""SQLAlchemy declarative base with standardized constraint naming."""
from sqlalchemy import MetaData
from sqlalchemy.orm import DeclarativeBase
# Stable constraint names so Alembic autogeneration produces clean diffs.
NAMING_CONVENTION = {
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(constraint_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
}
class Base(DeclarativeBase):
metadata = MetaData(naming_convention=NAMING_CONVENTION)