【问题标题】:SQLAlchemy-Migrate or Alembic deletes data when renaming modelSQLAlchemy-Migrate 或 Alembic 在重命名模型时删除数据
【发布时间】:2021-09-07 01:44:45
【问题描述】:

我正在使用 SQLAlchemy-Migrate 来管理我的 PostgreSQL 数据库的迁移。我为模型更改了__tablename__,运行迁移更改了数据库中的名称,但表中的所有行都被删除了。如何在不删除数据的情况下重命名模型?

class Contract(db.Model):
    __tablename__ = 'contract'
    id = db.Column(db.Integer, primary_key=True)
    is_valid = db.Column(db.Boolean, default=IS_VALID)

我将其从 contract 重命名为 contracts 并进行此迁移:

def upgrade(migrate_engine):
    pre_meta.bind = migrate_engine
    post_meta.bind = migrate_engine
    pre_meta.tables['contract'].drop()
    post_meta.tables['contracts'].create()

它会删除旧表并创建一个新表。我从未检查过其他迁移脚本,因为它们总是在不丢失数据的情况下运行。

【问题讨论】:

  • 请包括您的(相关)定义,包括更改前后的定义,以及您使用的迁移。换句话说,产生一个minimal reproducible example。听起来您已经尝试在构建类后在实时系统中为模型类的 __tablename__ 属性分配一个新值。正如您所知道的,这将不起作用,因为相应的 Table 对象是在类构造期间由声明式构造的。在 Postgresql 中重命名表很简单,不需要删除任何内容:ALTER TABLE the_table RENAME TO another_table;

标签: python sqlalchemy alembic sqlalchemy-migrate


【解决方案1】:

SQLAlchemy-Migrate 不知道数据库中名为“contracts”的表与代码中名为“contracts”的模型相同。它们是不同的名称,它只是做一个简单的比较。这就是为什么您总是检查生成的迁移脚本以确保它们做正确的事情。

SQLAlchemy-Migrate docs,使用rename 方法重命名表。

pre_meta.tables['contract'].rename('contracts')

如果您使用 Alembic(或 Flask-Alembic,或 Flask-Migrate)而不是 SQLAlchemy-Migrate,则会发生同样的事情。使用rename_table 方法。

op.rename_table('contract', 'contracts')

【讨论】:

    猜你喜欢
    • 2019-07-13
    • 2016-03-30
    • 2012-10-18
    • 2015-07-15
    • 2018-12-24
    • 1970-01-01
    • 2015-10-12
    • 1970-01-01
    相关资源
    最近更新 更多