jju*_*ien 7 python sqlalchemy alembic
我正在尝试使用带有MySQL引擎的alembic来执行在线迁移.我发现当我的onupgrade()方法中的操作失败时,我的数据库卡在一个不一致的状态,我不能使用alembic直到我手动清理在onupgrade()失败之前发生的任何操作
例:
def upgrade():
op.create_table('sometable',
Column('id', INTEGER, primary_key=True),
Column('name', VARCHAR(150), nullable=False, unique=True))
op.add_column('anothertable' Column('id', INTEGER))
op.create_table('secondtable')
Run Code Online (Sandbox Code Playgroud)
因此,如果我运行此操作并且op.add_column失败,即使我修复了add_column行,现在"sometable"也存在,因此第一个操作将始终失败.我无法运行我的降级脚本,因为alembic从未更新版本,因为它没有完成升级.
我在想是否有办法强制运行我的ondowngrade(),这可能有用.我必须忽略错误,因为肯定会有一些错误.就像放弃"第二表"一样.我无论如何都找不到这样做.
任何人都有一个很好的方法来处理这个?
小智 7
问题不在于alembic,而在于你使用MySQL,它无法回滚DDL语句.
因此,实现它的唯一(丑陋)方法是进行手动异常处理并逆转在此之前成功的操作.
这样的事情(写在我的脑海里,所以这不是最优雅的解决方案,甚至可能有点不对,但我希望你能得到主旨):
def upgrade():
try:
op.create_table('sometable',
Column('id', INTEGER, primary_key=True),
Column('name', VARCHAR(150), nullable=False, unique=True))
except:
try:
op.drop_table('sometable')
except:
pass
raise
try:
op.add_column('anothertable' Column('id', INTEGER))
except:
op.drop_table('sometable')
try:
op.drop_column('anothertable', 'id')
except:
pass
raise
try:
op.create_table('secondtable')
except:
op.drop_table('sometable')
op.drop_column('anothertable', 'id')
try:
op.drop_table('secondtable')
except:
pass
raise
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3268 次 |
| 最近记录: |