如何使用SQLAlchemy支持旧的模式版本?

时间:2016-05-06 11:45:20

标签: sqlalchemy alembic

我的应用程序使用庞大的数据库内容,我们无法始终迁移到我们在软件升级时设计的最新数据库模式版本。是的,我们正在使用数据库迁移工具(Alembic),但这还不允许我们拥有可以处理多个模式版本的Python应用程序代码。在接受系统停机时间的某个时间点,将执行到最新版本的迁移,但与此同时,应用程序代码需要能够处理两个(多个)版本。

因此,例如,如果已执行数据库迁移,我们只能提供功能X 。它还应该能够在尚未执行迁移的情况下运行,但是不会在功能X中提供日志中打印的警告。我在SQLAlchemy中看到了几种方法,但是他们都觉得很难看。我想就如何妥善处理这个问题提出一些建议。

示例:

Base = declarative_base()

class MyTable(Base):
    __tablename__ = 'my_table'

    id = Column(MyCustomType, nullable=False, primary_key=True)
    column_a = Column(Integer, nullable=True)
    column_b = Column(String(32))      # old schema
    column_b_new = Column(String(64))  # new schema

新架构版本有一个新列替换旧列。请注意,列名和列数据规范都会更改。

另一个要求是从代码的其他部分使用此类必须是透明的,以支持向后兼容性。该产品的其他组件稍后将了解新的列/数据类型。这意味着如果使用新架构初始化,旧属性仍然必须正常运行。因此,如果使用Mytable(column_a=123, column_b="abc")创建新对象,则它应该适用于新旧架构。

离开这里最好的方法是什么?我看到支持两种模式的选项:

  1. 为两个模式版本定义两个MyTable类,然后确定模式版本(如何?),并根据结果使用任一版本。通过这种方法,我认为这需要在每个地方使用MyTable类时使用哪种模式的逻辑,因此容易中断。将类属性相互链接(column_b = column_b_new)以实现向后兼容性(这实际上有效吗?)。
  2. 正常初始化数据库并根据检测到的架构版本更改MyTable类对象。我不确定SQLAlchemy是否支持在初始化后更改声明性基类的属性(列)。
  3. 创建一个自定义Mapper配置,如下所示:http://docs.sqlalchemy.org/en/rel_1_1/orm/extensions/declarative/basic_use.html#mapper-configuration我不知道如何从这个SQLAlchemy功能到我想要的解决方案。也许可以在自定义映射器函数中检查动态自定义属性集?

0 个答案:

没有答案