如何在事务中包装create和sqlalchemy迁移alter stations

如何在事务中包装create和sqlalchemy迁移alter stations,sqlalchemy,sqlalchemy-migrate,Sqlalchemy,Sqlalchemy Migrate,我正在尝试使用sqlalchemy table.create和sqlalchemy migrate table.rename方法,以及一些插入select stations的方法,对我的数据库进行一些数据库模式更改。我想把所有这些都打包在一个事务中。我不知道该怎么做。这就是我所尝试的: engine = sqlalchemy.engine_from_config(conf.local_conf, 'sqlalchemy.') trans = engine.connect().begin() tr

我正在尝试使用sqlalchemy table.create和sqlalchemy migrate table.rename方法,以及一些插入select stations的方法,对我的数据库进行一些数据库模式更改。我想把所有这些都打包在一个事务中。我不知道该怎么做。这就是我所尝试的:

engine = sqlalchemy.engine_from_config(conf.local_conf, 'sqlalchemy.')
trans = engine.connect().begin()
try:
    old_metatadata.tables['address'].rename('address_migrate_tmp', connection=trans)
    new_metatadata.tables['address'].create(connection=trans)
except:
    trans.rollback()
    raise
else:
    trans.commit()
但它的错误在于:

AttributeError: 'RootTransaction' object has no attribute '_run_visitor'

(我尝试使用sqlalchemy migrate column.alter(name='newname'),但这会导致错误,并且在事务中不起作用,因此使我的数据库处于中断状态。我还需要重命名多个列,因此我决定滚动我自己的代码。)

啊-我只需要使用创建事务的连接

engine = sqlalchemy.engine_from_config(conf.local_conf, 'sqlalchemy.')
conn = engine.connect()
trans = conn.begin()
try:
    old_metatadata.tables['address'].rename('address_migrate_tmp', connection=conn)
    new_metatadata.tables['address'].create(bind=conn)
except:
    trans.rollback()
    raise
else:
    trans.commit()

您必须记住在最后调用conn.close()。如果不这样做,一旦引入10多个迁移脚本(我认为这是sqlalchemy内部对池大小使用的限制),升级脚本就会有间歇性挂起的风险,因为它会在等待DB连接池时被阻塞,但只有在极少数情况下,python的GC才没有机会启动并关闭现有连接。