Alembic 使用现有的 SQLAlchemy 引擎迁移
Alembic migrate with existing SQLAlchemy engine
我有一个在 sqlite 内存数据库上创建的特定 SQLAlchemy 声明性基础:
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
我将其用于单元测试逻辑。
有了这个,我在数据库中有了我的表。但现在我想使用 alembic 迁移某些东西。
AFAIK alembic 迁移使用 env.py
run_migrations_online 并使用名为 engine_from_config
的 SQLAlchemy 函数在此处创建一个新引擎。
我想解决的问题是有一种方法可以使用先前创建的连接,其中包含最近创建的表,用于 alembic 迁移。
我在我的测试脚本中使用了这个:Using Alembic API from inside application code,所以我的脚本在之前的 create_all
调用之后执行以下操作:
import alembic.config
alembicArgs = ['--raiseerr', '-x', 'dbPath=sqlite:///:memory:', 'upgrade', 'head']
alembic.config.main(argv=alembicArgs
[请注意,我只是通过 Base.metadata.create_all(engine)
调用创建我的模式,但我的 alembic 版本不仅包含模式更改,它们还填充了一些目录表数据,这就是我打算使用 alembic 的原因这里。事实上,如果我的 alembic 迁移包含一些 "create tables" 逻辑,这两者就会发生冲突。所以我可以安全地删除 create_all
调用并单独依赖 alembic 在这里创建我的模式。]
已经修改了我的 alembic env.py
:
def run_migrations_online():
ini_section = config.get_section(config.config_ini_section)
db_path = context.get_x_argument(as_dictionary=True).get('dbPath')
if db_path:
ini_section['sqlalchemy.url'] = db_path
connectable = engine_from_config(
ini_section,
prefix ... # everything from here the same as default env.py
据我所知,connectable=engine_from_config
在新的 sqlite:///:memory:
数据库上创建了到新引擎的连接,这就是为什么我无法通过 alembic 升级之前在我的数据库上创建的数据库create_all(engine)
.
脚本
所以... TLDR;有没有办法将我以前存在的引擎连接(使用我创建的表)传递给 alembic,以便它可以迁移它? (我很确定我创建的 dbPath arg 在这里没有用,事实上,我只是复制我引用的其他 post 使用的内容)。
您可以创建一个 alembic 配置实例并对其进行操作:
def migrate_in_memory(migrations_path, alembic_ini_path=None, connection=None, revision="head"):
config = alembic.config.Config(alembic_ini_path)
config.set_main_option('script_location', migrations_path)
config.set_main_option('sqlalchemy.url', 'sqlite:///:memory:')
if connection is not None:
config.attributes['connection'] = connection
alembic.command.upgrade(config, revision)
它可能需要一些微调,但这是事情的一般要点。
我有一个在 sqlite 内存数据库上创建的特定 SQLAlchemy 声明性基础:
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
我将其用于单元测试逻辑。
有了这个,我在数据库中有了我的表。但现在我想使用 alembic 迁移某些东西。
AFAIK alembic 迁移使用 env.py
run_migrations_online 并使用名为 engine_from_config
的 SQLAlchemy 函数在此处创建一个新引擎。
我想解决的问题是有一种方法可以使用先前创建的连接,其中包含最近创建的表,用于 alembic 迁移。
我在我的测试脚本中使用了这个:Using Alembic API from inside application code,所以我的脚本在之前的 create_all
调用之后执行以下操作:
import alembic.config
alembicArgs = ['--raiseerr', '-x', 'dbPath=sqlite:///:memory:', 'upgrade', 'head']
alembic.config.main(argv=alembicArgs
[请注意,我只是通过 Base.metadata.create_all(engine)
调用创建我的模式,但我的 alembic 版本不仅包含模式更改,它们还填充了一些目录表数据,这就是我打算使用 alembic 的原因这里。事实上,如果我的 alembic 迁移包含一些 "create tables" 逻辑,这两者就会发生冲突。所以我可以安全地删除 create_all
调用并单独依赖 alembic 在这里创建我的模式。]
已经修改了我的 alembic env.py
:
def run_migrations_online():
ini_section = config.get_section(config.config_ini_section)
db_path = context.get_x_argument(as_dictionary=True).get('dbPath')
if db_path:
ini_section['sqlalchemy.url'] = db_path
connectable = engine_from_config(
ini_section,
prefix ... # everything from here the same as default env.py
据我所知,connectable=engine_from_config
在新的 sqlite:///:memory:
数据库上创建了到新引擎的连接,这就是为什么我无法通过 alembic 升级之前在我的数据库上创建的数据库create_all(engine)
.
所以... TLDR;有没有办法将我以前存在的引擎连接(使用我创建的表)传递给 alembic,以便它可以迁移它? (我很确定我创建的 dbPath arg 在这里没有用,事实上,我只是复制我引用的其他 post 使用的内容)。
您可以创建一个 alembic 配置实例并对其进行操作:
def migrate_in_memory(migrations_path, alembic_ini_path=None, connection=None, revision="head"):
config = alembic.config.Config(alembic_ini_path)
config.set_main_option('script_location', migrations_path)
config.set_main_option('sqlalchemy.url', 'sqlite:///:memory:')
if connection is not None:
config.attributes['connection'] = connection
alembic.command.upgrade(config, revision)
它可能需要一些微调,但这是事情的一般要点。