From 09b0240adc9100e9fe65fc6b76e1f7e563a8ccb7 Mon Sep 17 00:00:00 2001 From: Alex TYRODE Date: Sun, 4 May 2025 23:13:27 +0000 Subject: [PATCH] refactor: update database migration strategy and schema creation - Modified the `init_db` function to let Alembic handle schema creation, removing the explicit schema creation step. - Updated the `migrate_canvas_data` migration to depend on the new `create_schema` migration, ensuring proper order of operations. - Introduced a new migration file `create_schema.py` to explicitly create the database schema, improving migration reliability. --- src/backend/database/database.py | 3 +- .../2025_05_02_2055-migrate_canvas_data.py | 2 +- .../versions/2025_05_04_2310-create_schema.py | 46 +++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 src/backend/database/migrations/versions/2025_05_04_2310-create_schema.py diff --git a/src/backend/database/database.py b/src/backend/database/database.py index c08e712..7f81c1a 100644 --- a/src/backend/database/database.py +++ b/src/backend/database/database.py @@ -184,9 +184,8 @@ async def run_migrations() -> None: async def init_db() -> None: """Initialize the database with required tables""" - # Create schema and tables + # Only create tables, let Alembic handle schema creation async with engine.begin() as conn: - await conn.execute(CreateSchema(SCHEMA_NAME, if_not_exists=True)) await conn.run_sync(Base.metadata.create_all) async def get_session() -> AsyncGenerator[AsyncSession, None]: diff --git a/src/backend/database/migrations/versions/2025_05_02_2055-migrate_canvas_data.py b/src/backend/database/migrations/versions/2025_05_02_2055-migrate_canvas_data.py index db1b300..18098e7 100644 --- a/src/backend/database/migrations/versions/2025_05_02_2055-migrate_canvas_data.py +++ b/src/backend/database/migrations/versions/2025_05_02_2055-migrate_canvas_data.py @@ -17,7 +17,7 @@ # revision identifiers, used by Alembic. revision = 'migrate_canvas_data' -down_revision = None +down_revision = 'create_schema' # This migration depends on the schema creation branch_labels = None depends_on = None diff --git a/src/backend/database/migrations/versions/2025_05_04_2310-create_schema.py b/src/backend/database/migrations/versions/2025_05_04_2310-create_schema.py new file mode 100644 index 0000000..70753e5 --- /dev/null +++ b/src/backend/database/migrations/versions/2025_05_04_2310-create_schema.py @@ -0,0 +1,46 @@ +"""Create schema explicitly + +Revision ID: create_schema +Revises: +Create Date: 2025-05-04 23:10:00.000000 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + +# Import the schema name from the models using dynamic import +import importlib.util +import os + +# Get the absolute path to the base_model module +base_model_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "models", "base_model.py") + +# Load the module dynamically +spec = importlib.util.spec_from_file_location("base_model", base_model_path) +base_model = importlib.util.module_from_spec(spec) +spec.loader.exec_module(base_model) + +# Get SCHEMA_NAME from the loaded module +SCHEMA_NAME = base_model.SCHEMA_NAME + +# revision identifiers, used by Alembic. +revision: str = 'create_schema' +down_revision: Union[str, None] = None # This is the first migration +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Create schema explicitly before other operations.""" + # Create schema using execute() with a SQL string instead of CreateSchema + # This approach can be more reliable in certain PostgreSQL versions + op.execute(f"CREATE SCHEMA IF NOT EXISTS {SCHEMA_NAME}") + + +def downgrade() -> None: + """Drop schema if needed.""" + # We don't actually want to drop the schema on downgrade + # as it would delete all data, but the function is required + pass