sqlalchemy 的 schema 合并模块 alembic 使用
alembic 很好的解决了升级数据库改变表结构的传统难题,官方的推荐用法是当一个工具用,这是从 Stack Overflow 扒到的直接用内部 api 的代码,操作有点像 diff_patch。
mc = MigrationContext.configure(engine.connect())
# diff = compare_metadata(mc, Base.metadata)
# print(diff)
mg = produce_migrations(mc, Base.metadata)
operation = Operations(mc)
for outer_op in mg.upgrade_ops.ops:
if isinstance(outer_op, OpContainer):
for inner_op in outer_op.ops:
# logger.info("Invoking %s", inner_op)
operation.invoke(inner_op)
else:
operation.invoke(outer_op)
例如,第一次执行:
Base = declarative_base()
class User(Base):
__tablename__ = "user_account"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(30))
fullname = Column(String)
Base.metadata.create_all(engine)
建立表 user_account。
第二次增加一个 profile 字段
class User(Base):
__tablename__ = "user_account"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(30))
fullname = Column(String)
profile = Column(String)
Base.metadata.create_all(engine) # 表已存在,不会执行任何动作,但后面会提示缺少 profile 字段
用上面的 migrate 操作后输出:
sqlalchemy.engine.Engine ALTER TABLE user_account ADD COLUMN profile VARCHAR
显然也可以用于创建表。
这是一种轻量式的用法。对于严肃的用途,还是使用官方的工具式用法结合版本管理更稳当。