如何使用Alembic完成SQLAlchemy UUIDField的as_uuid参数变更迁移
调整UUID字段as_uuid参数的Alembic迁移方案
首先明确基础逻辑:as_uuid是SQLAlchemy UUID类型的客户端侧参数,仅控制ORM读取字段时返回Python原生uuid.UUID对象还是十六进制字符串,不会修改数据库侧的存储格式,所以Alembic的自动检测逻辑默认不会识别该参数变更,分两种场景处理:
场景1:仅调整ORM侧参数,无需修改数据库存储
如果只是需要ORM返回字符串格式的UUID,不需要修改数据库里的存储内容,直接在模型定义里把as_uuid=True改成as_uuid=False即可,不需要编写任何Alembic迁移脚本,不会影响现有数据的读写。
场景2:需要同步修改数据库侧存储类型(比如原生UUID转字符串存储)
如果业务要求把数据库层的原生UUID类型转为字符串格式存储,需要手动编写迁移脚本,步骤如下:
- 生成空白迁移文件
alembic revision -m "adjust uuid as_uuid parameter to false and modify field type"
- 按以下逻辑编写迁移脚本,注意带外键的字段需要先删除外键约束、修改字段类型后再加回约束,避免报错:
from alembic import op import sqlalchemy as sa # 替换为你实际的外键约束名,可通过数据库查询获取 FOREIGN_KEY_NAME = "model1_model_uuid_fkey" def upgrade(): # 删除外键约束 op.drop_constraint(FOREIGN_KEY_NAME, "model1", type_="foreignkey") # 修改主表uuid字段类型,示例为PostgreSQL转CHAR(36),MySQL可改为VARCHAR(36) op.alter_column( "model", "uuid", type_=sa.CHAR(36), existing_type=sa.UUID(), existing_nullable=True ) # 修改关联表外键字段类型,和主表保持一致 op.alter_column( "model1", "uuid", # 替换为Model1中实际的外键字段名 type_=sa.CHAR(36), existing_type=sa.UUID(), existing_nullable=False ) # 重新创建外键约束 op.create_foreign_key( FOREIGN_KEY_NAME, "model1", "model", ["uuid"], # Model1的外键字段名 ["uuid"] # Model的关联字段名 ) def downgrade(): # 回滚逻辑为upgrade的反向操作 op.drop_constraint(FOREIGN_KEY_NAME, "model1", type_="foreignkey") op.alter_column( "model1", "uuid", type_=sa.UUID(), existing_type=sa.CHAR(36), existing_nullable=False ) op.alter_column( "model", "uuid", type_=sa.UUID(), existing_type=sa.CHAR(36), existing_nullable=True ) op.create_foreign_key( FOREIGN_KEY_NAME, "model1", "model", ["uuid"], ["uuid"] )
注意事项
- 执行迁移前必须备份全量数据,避免类型转换过程中出现数据丢失
- 外键约束名可通过数据库语句查询:
SELECT constraint_name FROM information_schema.table_constraints WHERE table_name = 'model1' AND constraint_type = 'FOREIGN KEY'; - 如果不需要修改数据库字段类型,可直接删除upgrade和downgrade函数内的所有逻辑,仅保留空函数即可满足Alembic的版本校验要求
内容的提问来源于stack exchange,提问作者AOL
相关产品推荐
相关产品推荐

