mail notification

This commit is contained in:
Bastian Wagner
2026-08-15 20:47:02 +02:00
parent 7c9e19ba0b
commit 2aba1265af
16 changed files with 519 additions and 2 deletions

View File

@@ -1,9 +1,21 @@
from sqlalchemy import create_engine
from sqlalchemy import create_engine, inspect, text
from sqlalchemy.engine import Engine
from sqlalchemy.orm import Session, sessionmaker
from app.db.models import Base
# Columns added to existing tables after their initial release. create_all()
# only creates missing tables, never adds columns to tables that already
# exist, so a column added to a model here must also be listed below or an
# already-deployed database will never receive it and the app will crash
# reading/writing that column.
_ADDITIVE_COLUMNS: dict[str, list[tuple[str, str]]] = {
"sync_users": [
("notify_email_enabled", "BOOLEAN NOT NULL DEFAULT 0"),
("notification_email", "VARCHAR(255)"),
],
}
def create_db_engine(database_url: str) -> Engine:
connect_args = {"check_same_thread": False} if database_url.startswith("sqlite") else {}
@@ -16,3 +28,24 @@ def create_session_factory(engine: Engine) -> sessionmaker[Session]:
def initialize_schema(engine: Engine) -> None:
Base.metadata.create_all(engine)
_apply_additive_migrations(engine)
def _apply_additive_migrations(engine: Engine) -> None:
if engine.dialect.name != "sqlite":
# ALTER TABLE ... ADD COLUMN syntax/type names below are only
# verified against sqlite, the only backend this app is deployed
# against; a fresh create_all() on another backend already has every
# current column, so skipping here only matters for a pre-existing
# non-sqlite database, which does not exist in practice.
return
inspector = inspect(engine)
existing_tables = set(inspector.get_table_names())
with engine.begin() as conn:
for table, columns in _ADDITIVE_COLUMNS.items():
if table not in existing_tables:
continue
existing_columns = {col["name"] for col in inspector.get_columns(table)}
for name, ddl_type in columns:
if name not in existing_columns:
conn.execute(text(f"ALTER TABLE {table} ADD COLUMN {name} {ddl_type}"))