FastAPI中执行alembic upgrade head失败,报错'get_main_option'属性缺失
FastAPI中调用Alembic迁移报错解决方案
问题根源
调用command.upgrade时参数顺序错误。run_sync会自动将当前同步Connection对象作为第一个参数传给目标函数,但Alembic的command.upgrade要求第一个参数是配置对象,导致Connection被误当作Config传入,触发get_main_option不存在的错误。
两种解决方法
方法1:Lambda包装调整参数顺序
直接修改run_sync的调用逻辑,用lambda屏蔽run_sync自动传入的Connection,传递正确的参数给command.upgrade:
async def run_migrations(): alembic_cfg = config.Config("alembic.ini") alembic_cfg.set_main_option("sqlalchemy.url", get_db_url()) async with engine.begin() as alembic_conn: # 用lambda接收conn但不传递给upgrade,手动传入配置和版本 await alembic_conn.run_sync(lambda _: command.upgrade(alembic_cfg, "head"))
方法2:修改alembic/env.py适配异步连接(官方推荐)
这种方式更贴合Alembic的异步迁移设计,能更好地复用连接和配置:
- 更新
alembic/env.py中的run_migrations_online函数:
from alembic import context from sqlalchemy import pool from sqlalchemy.ext.asyncio import AsyncEngine # 保留原有导入和metadata等配置代码... def run_migrations_online(): # 优先使用传入的连接 connectable = context.config.attributes.get("connection", None) if not connectable: # 命令行模式创建异步引擎 connectable = AsyncEngine( create_async_engine( context.config.get_main_option("sqlalchemy.url"), poolclass=pool.NullPool, ) ) async def execute_migrations(): async with connectable.connect() as conn: await conn.run_sync(do_run_migrations) await connectable.dispose() import asyncio asyncio.run(execute_migrations()) def do_run_migrations(connection): context.configure(connection=connection) with context.begin_transaction(): context.run_migrations()
- 修改FastAPI中的迁移调用代码,将当前连接注入Alembic配置:
async def run_migrations(): alembic_cfg = config.Config("alembic.ini") alembic_cfg.set_main_option("sqlalchemy.url", get_db_url()) async with engine.begin() as alembic_conn: # 将同步连接注入配置属性 alembic_cfg.attributes["connection"] = alembic_conn.sync_connection command.upgrade(alembic_cfg, "head")
验证
修改后重启FastAPI,迁移操作即可正常执行,不再触发AttributeError。
内容的提问来源于stack exchange,提问作者Jon Hayden
相关产品推荐
相关产品推荐

