28 lines
1.3 KiB
Python
28 lines
1.3 KiB
Python
"""Small, dependency-free schema migrations for the deployed SQLite database."""
|
|
from sqlalchemy import inspect, text
|
|
|
|
from .extensions import db
|
|
|
|
|
|
def upgrade_schema() -> None:
|
|
"""Create new tables and add authentication columns without losing existing data."""
|
|
with db.engine.begin() as connection:
|
|
# Gunicorn workers can import the application simultaneously. Acquiring
|
|
# SQLite's write lock before inspecting or creating tables serializes the
|
|
# first-start migration and prevents duplicate CREATE TABLE attempts.
|
|
if db.engine.dialect.name == "sqlite":
|
|
connection.exec_driver_sql("BEGIN IMMEDIATE")
|
|
db.metadata.create_all(bind=connection)
|
|
inspector = inspect(connection)
|
|
columns = {item["name"] for item in inspector.get_columns("users")}
|
|
additions = {
|
|
"email": "VARCHAR(254)",
|
|
"email_verified_at": "DATETIME",
|
|
"is_active_account": "BOOLEAN NOT NULL DEFAULT 0",
|
|
"auth_version": "INTEGER NOT NULL DEFAULT 1",
|
|
}
|
|
for name, sql_type in additions.items():
|
|
if name not in columns:
|
|
connection.execute(text(f"ALTER TABLE users ADD COLUMN {name} {sql_type}"))
|
|
connection.execute(text("CREATE UNIQUE INDEX IF NOT EXISTS ix_users_email_unique ON users (email) WHERE email IS NOT NULL"))
|