Skip to content

Commit e8550e5

Browse files
authored
refactor: update database migration strategy and schema creation (#79)
- 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.
1 parent 3f613b6 commit e8550e5

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

src/backend/database/database.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,8 @@ async def run_migrations() -> None:
184184

185185
async def init_db() -> None:
186186
"""Initialize the database with required tables"""
187-
# Create schema and tables
187+
# Only create tables, let Alembic handle schema creation
188188
async with engine.begin() as conn:
189-
await conn.execute(CreateSchema(SCHEMA_NAME, if_not_exists=True))
190189
await conn.run_sync(Base.metadata.create_all)
191190

192191
async def get_session() -> AsyncGenerator[AsyncSession, None]:

src/backend/database/migrations/versions/2025_05_02_2055-migrate_canvas_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
# revision identifiers, used by Alembic.
1919
revision = 'migrate_canvas_data'
20-
down_revision = None
20+
down_revision = 'create_schema' # This migration depends on the schema creation
2121
branch_labels = None
2222
depends_on = None
2323

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""Create schema explicitly
2+
3+
Revision ID: create_schema
4+
Revises:
5+
Create Date: 2025-05-04 23:10:00.000000
6+
7+
"""
8+
from typing import Sequence, Union
9+
10+
from alembic import op
11+
import sqlalchemy as sa
12+
13+
# Import the schema name from the models using dynamic import
14+
import importlib.util
15+
import os
16+
17+
# Get the absolute path to the base_model module
18+
base_model_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "models", "base_model.py")
19+
20+
# Load the module dynamically
21+
spec = importlib.util.spec_from_file_location("base_model", base_model_path)
22+
base_model = importlib.util.module_from_spec(spec)
23+
spec.loader.exec_module(base_model)
24+
25+
# Get SCHEMA_NAME from the loaded module
26+
SCHEMA_NAME = base_model.SCHEMA_NAME
27+
28+
# revision identifiers, used by Alembic.
29+
revision: str = 'create_schema'
30+
down_revision: Union[str, None] = None # This is the first migration
31+
branch_labels: Union[str, Sequence[str], None] = None
32+
depends_on: Union[str, Sequence[str], None] = None
33+
34+
35+
def upgrade() -> None:
36+
"""Create schema explicitly before other operations."""
37+
# Create schema using execute() with a SQL string instead of CreateSchema
38+
# This approach can be more reliable in certain PostgreSQL versions
39+
op.execute(f"CREATE SCHEMA IF NOT EXISTS {SCHEMA_NAME}")
40+
41+
42+
def downgrade() -> None:
43+
"""Drop schema if needed."""
44+
# We don't actually want to drop the schema on downgrade
45+
# as it would delete all data, but the function is required
46+
pass

0 commit comments

Comments
 (0)