SQLAlchemy与Alembic的DRY用法:如何避免迁移时重复编写列定义
解决方案
方案1:使用Alembic自动生成迁移(最推荐)
你已经在项目中定义好了完整的ORM模型,直接运行自动生成命令即可完成所有迁移代码的生成,无需手动编写列定义:
alembic revision --autogenerate -m "初始化18张业务表"
Alembic会自动对比当前Declarative Base下所有模型的结构,生成对应的op.create_table语句,所有列属性、约束、索引都会自动填充,你只需要执行命令后核对生成的代码是否符合预期即可,完全避免手动编写200个列的重复工作。
方案2:手动定义版本模型后批量生成表
如果你需要完全手动控制迁移文件的内容,可以按你说的将当前版本的模型定义复制到迁移文件中,之后无需逐个传递列参数,直接用模型内置的表结构对象生成建表语句:
步骤1:在迁移文件中定义版本级别的模型
import sqlalchemy as sa from sqlalchemy.ext.declarative import declarative_base from alembic import op # 迁移文件内独立的Base,和项目现有模型完全隔离 MigrationBase = declarative_base() # 直接粘贴当前版本的18个模型定义即可,无需修改 class Account(MigrationBase): __tablename__ = "account" id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(50), nullable=False) description = sa.Column(sa.Unicode(200)) # 其余模型按同样规则粘贴
步骤2:简化upgrade函数写法
方式A:逐个建表(更可控,推荐)
每个表只需要2行代码即可完成建表,无需手动列所有列:
def upgrade(): # 建account表 op.create_table( Account.__tablename__, *Account.__table__.c ) # 其余17个表按同样格式添加即可
方式B:批量建所有表(更简洁)
如果需要一次性建所有复制进来的模型对应的表,直接调用metadata的create_all方法即可:
def upgrade(): bind = op.get_bind() MigrationBase.metadata.create_all(bind=bind)
注意事项
因为迁移文件中的模型是独立定义的,和你项目后续迭代的模型完全隔离,所以不会出现后续模型变更破坏历史迁移的问题,完全符合迁移文件的可复现要求。
内容的提问来源于stack exchange,提问作者teebagz
相关产品推荐
相关产品推荐

