如何为 Alembic 编写可移植的布尔列
How to write portable Boolean columns for Alembic
我正在开发一个 Flask 应用程序,使用 Flask-Migrate(因此也使用 Alembic)来管理对数据库的更改。我 运行 很早就遇到了一个问题,即更改某些 not-nullable 布尔列会触发基础数据库中的错误。
我正在删除一个布尔列,并重命名另一列(相当于两次删除和一次添加)。
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('user', sa.Column('is_enabled', sa.Boolean(), nullable=False))
op.drop_column('user', 'is_disabled')
op.drop_column('user', 'is_deleted')
# ### end Alembic commands ###
由于数据库中已有数据,因此添加需要一个默认值以用于现有行。但是,SQLAlchemy 人员 already passed 在布尔列中添加对 server_default
的(便携式)支持。
鉴于这些条件,是否有任何方法可以进行此迁移并保持数据库的可移植性,或者我是否需要将代码限制在一个数据库中,并开始根据底层数据库驱动程序编写 server_default
值布尔列?
是的,您可以更改升级(也可能还有降级)功能来实现您想要的。另请注意,您当前的升级不会保留现有数据,因为您正在添加新列并删除旧列。由于 alembic 无法检测到重命名,您需要更改升级(和降级)自动生成的函数。
要通过回填数据库实现您想要的效果:
- Add/rename 没有
nullable
约束的列。
- 当当前值为
Null
时,用默认值回填现有行。
- 更改列以包含
nullable
约束:
要解决重命名问题,您需要将添加和删除行更改为 1 个更改行:
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('user', 'is_disabled', new_column_name='is_enabled')
op.execute('update user set is_disabled=false where is_disabled is null')
op.alter_column('user', 'is_enabled', nullable=False)
op.drop_column('user', 'is_deleted')
# ### end Alembic commands ###
此外,当您将 is_disabled
更改为 is_enabled
时,您可以根据需要使用 op.execute
切换布尔值。
我正在开发一个 Flask 应用程序,使用 Flask-Migrate(因此也使用 Alembic)来管理对数据库的更改。我 运行 很早就遇到了一个问题,即更改某些 not-nullable 布尔列会触发基础数据库中的错误。
我正在删除一个布尔列,并重命名另一列(相当于两次删除和一次添加)。
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('user', sa.Column('is_enabled', sa.Boolean(), nullable=False))
op.drop_column('user', 'is_disabled')
op.drop_column('user', 'is_deleted')
# ### end Alembic commands ###
由于数据库中已有数据,因此添加需要一个默认值以用于现有行。但是,SQLAlchemy 人员 already passed 在布尔列中添加对 server_default
的(便携式)支持。
鉴于这些条件,是否有任何方法可以进行此迁移并保持数据库的可移植性,或者我是否需要将代码限制在一个数据库中,并开始根据底层数据库驱动程序编写 server_default
值布尔列?
是的,您可以更改升级(也可能还有降级)功能来实现您想要的。另请注意,您当前的升级不会保留现有数据,因为您正在添加新列并删除旧列。由于 alembic 无法检测到重命名,您需要更改升级(和降级)自动生成的函数。
要通过回填数据库实现您想要的效果:
- Add/rename 没有
nullable
约束的列。 - 当当前值为
Null
时,用默认值回填现有行。 - 更改列以包含
nullable
约束:
要解决重命名问题,您需要将添加和删除行更改为 1 个更改行:
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('user', 'is_disabled', new_column_name='is_enabled')
op.execute('update user set is_disabled=false where is_disabled is null')
op.alter_column('user', 'is_enabled', nullable=False)
op.drop_column('user', 'is_deleted')
# ### end Alembic commands ###
此外,当您将 is_disabled
更改为 is_enabled
时,您可以根据需要使用 op.execute
切换布尔值。