SQLAlchemy-Migrate 或 Alembic 重命名模型时删除数据

问题描述 投票:0回答:3

我正在使用 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()

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

python sqlalchemy alembic sqlalchemy-migrate
3个回答
23
投票

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

SQLAlchemy-Migrate 文档,使用

rename
方法重命名表。

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

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

rename_table
方法。

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

1
投票

我在使用时遇到了类似的问题

op.rename_table("old_name", "new_name")

我不断得到

psycopg2.errors.DuplicateTable:关系“new_name”已经存在

最后,我用了

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    # op.drop_table('uploaded_resource')
    op.drop_table('sessions')
    
    op.execute('DROP TABLE IF EXISTS new_name')
    op.execute('ALTER TABLE old_name RENAME TO new_name')
    op.execute('ALTER SEQUENCE old_name_id_seq RENAME TO new_name_id_seq')
    op.execute('ALTER INDEX old_name_pkey RENAME TO new_name_pkey')
    ....

def downgrade():
    ...
    op.execute('ALTER TABLE new_name RENAME TO old_name')
    op.execute('ALTER SEQUENCE new_name_id_seq RENAME TO old_name_id_seq')
    op.execute('ALTER INDEX new_name_pkey RENAME TO old_name_pkey')

这不太理想。

这也有一定帮助 https://petegraham.co.uk/rename-postgres-table-with-alembic/


0
投票

只是添加到@davidism的答案中,在使用

op.rename_table()
功能时,您应该确保也添加相关的降级代码。

例如: 如果您的

op.renam_table('table_name', 'new_table_name')
函数中有
upgrade()
,那么您需要在
op.rename_table('new_table_name', 'table_name')
函数中包含
downgrade()
,以防出现任何问题。

希望这对看到这个的人有所帮助,因为这已经是一个老问题了。

© www.soinside.com 2019 - 2024. All rights reserved.