Update database setup to include simple migrations and enhance .gitignore
- Added the `run_simple_migrations` function call in the database initialization process to ensure any missing columns are added during setup. - Updated the .gitignore file to exclude the `models_old.py` file, improving project cleanliness.
This commit is contained in:
@@ -16,3 +16,4 @@ __pycache__/
|
|||||||
*.pid
|
*.pid
|
||||||
locales/ru_backup.json
|
locales/ru_backup.json
|
||||||
locales/en_backup.json
|
locales/en_backup.json
|
||||||
|
db/models_old.py
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from sqlalchemy.orm import sessionmaker
|
|||||||
|
|
||||||
from config.settings import Settings
|
from config.settings import Settings
|
||||||
from .models import Base
|
from .models import Base
|
||||||
|
from .migrator import run_simple_migrations
|
||||||
|
|
||||||
async_engine = None
|
async_engine = None
|
||||||
|
|
||||||
@@ -62,6 +63,8 @@ async def init_db(settings: Settings, session_factory: sessionmaker):
|
|||||||
|
|
||||||
async with async_engine.begin() as conn:
|
async with async_engine.begin() as conn:
|
||||||
await conn.run_sync(Base.metadata.create_all)
|
await conn.run_sync(Base.metadata.create_all)
|
||||||
|
# Run lightweight, idempotent migrations to add any missing columns
|
||||||
|
await conn.run_sync(run_simple_migrations)
|
||||||
logging.info(
|
logging.info(
|
||||||
"PostgreSQL database initialized/checked successfully using SQLAlchemy."
|
"PostgreSQL database initialized/checked successfully using SQLAlchemy."
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import logging
|
||||||
|
from typing import Set
|
||||||
|
|
||||||
|
from sqlalchemy import inspect, text
|
||||||
|
from sqlalchemy.engine import Connection
|
||||||
|
|
||||||
|
from .models import Base
|
||||||
|
|
||||||
|
|
||||||
|
def _add_missing_columns(connection: Connection) -> None:
|
||||||
|
inspector = inspect(connection)
|
||||||
|
metadata = Base.metadata
|
||||||
|
|
||||||
|
existing_tables: Set[str] = set(inspector.get_table_names())
|
||||||
|
|
||||||
|
for table in metadata.tables.values():
|
||||||
|
table_name = table.name
|
||||||
|
if table_name not in existing_tables:
|
||||||
|
# Tables are created elsewhere via create_all; skip here.
|
||||||
|
continue
|
||||||
|
|
||||||
|
existing_columns = {col_info["name"] for col_info in inspector.get_columns(table_name)}
|
||||||
|
|
||||||
|
for desired_column in table.columns:
|
||||||
|
if desired_column.name in existing_columns:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Build ADD COLUMN DDL
|
||||||
|
preparer = connection.dialect.identifier_preparer
|
||||||
|
table_quoted = preparer.format_table(table)
|
||||||
|
column_name_quoted = preparer.quote(desired_column.name)
|
||||||
|
column_type_sql = desired_column.type.compile(dialect=connection.dialect)
|
||||||
|
|
||||||
|
default_clause = ""
|
||||||
|
server_default = getattr(desired_column, "server_default", None)
|
||||||
|
if server_default is not None and getattr(server_default, "arg", None) is not None:
|
||||||
|
try:
|
||||||
|
compiled_default = str(
|
||||||
|
server_default.arg.compile(dialect=connection.dialect)
|
||||||
|
)
|
||||||
|
default_clause = f" DEFAULT {compiled_default}"
|
||||||
|
except Exception: # best-effort
|
||||||
|
pass
|
||||||
|
|
||||||
|
# For safety, add new columns as NULLable to avoid failures on existing rows
|
||||||
|
# If strict NOT NULL is needed, it can be enforced manually later.
|
||||||
|
ddl = f"ALTER TABLE {table_quoted} ADD COLUMN {column_name_quoted} {column_type_sql}{default_clause}"
|
||||||
|
|
||||||
|
logging.info(
|
||||||
|
f"Migrator: adding missing column {desired_column.name} to table {table_name}"
|
||||||
|
)
|
||||||
|
connection.execute(text(ddl))
|
||||||
|
|
||||||
|
|
||||||
|
def run_simple_migrations(connection: Connection) -> None:
|
||||||
|
"""
|
||||||
|
Run lightweight, idempotent migrations:
|
||||||
|
- Ensure missing columns are added to existing tables to match models in db/models.py
|
||||||
|
Note: Table creation is handled separately via Base.metadata.create_all.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
_add_missing_columns(connection)
|
||||||
|
logging.info("Migrator: schema synchronized (columns added as needed).")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Migrator: failed to run simple migrations: {e}", exc_info=True)
|
||||||
|
raise
|
||||||
Reference in New Issue
Block a user