I've been looking at this for a while and not having any luck. If I run "alembic upgrade head" from the command line, it works great. I would like to do that from within FastAPI so when it starts up, it upgrades the database schema. So from lots of searching, I came up with this method:
async def run_migrations():
alembic_cfg = Config("alembic.ini")
url = str(engine.url)
async with engine.begin() as conn:
await conn.run_sync(alembic_cfg.set_main_option, "sqlalchemy.url", url)
await conn.run_sync(command.upgrade, alembic_cfg, "head")
I call it during the FastAPI lifespan startup. It gives me this error:
TypeError: Config.set_main_option() takes 3 positional arguments but 4 were given
I've also tried:
await conn.run_sync(alembic_cfg.set_main_option("sqlalchemy.url", url))
But that gives me:
TypeError: 'NoneType' object is not callable
Does run_sync not like the way I'm doing this? I'm not passing 4 arguments to set_main_option. The value of url is correct because I printed it out to make sure.
Or is there an easier/better way of doing an upgrade to head from within fastapi?
Thanks
Probably the issue that you try to set the sqlalchemy.url
in Alembic's Config object within the run_sync
function. It should work if you update the code like this:
async def run_migrations():
alembic_cfg = Config("alembic.ini")
url = str(engine.url)
alembic_cfg.set_main_option("sqlalchemy.url", url)
async with engine.begin() as conn:
await conn.run_sync(command.upgrade, alembic_cfg, "head")