Merge pull request 'refactor: Enhance Alembic migration functions to support direct execution and improve error handling for database URL configuration' (#28) from ph4 into prod

Reviewed-on: #28
This commit is contained in:
mo 2025-06-01 17:30:01 +02:00
commit 5e79be16d3
2 changed files with 19 additions and 21 deletions

View File

@ -53,8 +53,13 @@ def do_run_migrations(connection):
with context.begin_transaction(): with context.begin_transaction():
context.run_migrations() context.run_migrations()
async def run_migrations_online_async(): async def run_migrations_online_async(alembic_cfg=None):
"""Run migrations in 'online' mode asynchronously.""" """Run migrations in 'online' mode asynchronously."""
# If running from Alembic directly
if alembic_cfg:
if alembic_cfg.config_file_name is not None:
fileConfig(alembic_cfg.config_file_name)
connectable = create_async_engine( connectable = create_async_engine(
settings.DATABASE_URL, settings.DATABASE_URL,
poolclass=pool.NullPool, poolclass=pool.NullPool,
@ -77,9 +82,11 @@ def run_migrations_offline():
script output. script output.
""" """
url = config.get_main_option("sqlalchemy.url") if not settings.DATABASE_URL:
raise ValueError("DATABASE_URL not found in settings for Alembic.")
context.configure( context.configure(
url=url, url=settings.DATABASE_URL,
target_metadata=target_metadata, target_metadata=target_metadata,
literal_binds=True, literal_binds=True,
dialect_opts={"paramstyle": "named"}, dialect_opts={"paramstyle": "named"},
@ -88,8 +95,8 @@ def run_migrations_offline():
with context.begin_transaction(): with context.begin_transaction():
context.run_migrations() context.run_migrations()
# This section only runs when executing alembic commands directly (not when imported)
if context.is_offline_mode(): if context.is_offline_mode():
run_migrations_offline() run_migrations_offline()
else: elif 'ALEMBIC_CONFIG' in os.environ: # Only run if called from alembic command
# Don't run migrations here - they will be run from FastAPI asyncio.run(run_migrations_online_async(context.config))
pass

View File

@ -219,25 +219,16 @@ async def run_migrations():
"""Run database migrations.""" """Run database migrations."""
try: try:
logger.info("Running database migrations...") logger.info("Running database migrations...")
# Get the absolute path to the alembic.ini file # Get the absolute path to the alembic directory
base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
alembic_ini_path = os.path.join(base_path, 'alembic.ini') alembic_path = os.path.join(base_path, 'alembic')
alembic_cfg = Config(alembic_ini_path)
# Set the script_location to the absolute path # Add alembic directory to Python path
script_location = os.path.join(base_path, 'alembic') if alembic_path not in sys.path:
alembic_cfg.set_main_option('script_location', script_location) sys.path.insert(0, alembic_path)
# Set the sqlalchemy.url # Import and run migrations
if not settings.DATABASE_URL:
raise ValueError("DATABASE_URL is not configured in settings.")
alembic_cfg.set_main_option('sqlalchemy.url', settings.DATABASE_URL)
# Import the async migration function from env.py
sys.path.insert(0, script_location)
from env import run_migrations_online_async from env import run_migrations_online_async
# Run the migration asynchronously
await run_migrations_online_async() await run_migrations_online_async()
logger.info("Database migrations completed successfully.") logger.info("Database migrations completed successfully.")