【问题标题】:How to use Flask-Migrate to do database migration?如何使用 Flask-Migrate 进行数据库迁移?
【发布时间】:2018-10-29 14:16:16
【问题描述】:

我在使用 Flask-Migrate 升级/降级数据库时遇到问题。有两个表,UserPost,由以下类定义:

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    password_hash = db.Column(db.String(128))
    posts = db.relationship('Post', backref='author', lazy='dynamic')

    def __repr__(self):
        return '<User {}>'.format(self.username)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id')) 

我在这些表中添加了一些条目。

现在的问题。 :)

为了好玩,我通过:dummy = db.Column(db.String(20))User 表中添加了一个列。修改表架构后,我运行了以下命令:

  1. flask db migrate----成功
  2. flask db upgrade----成功

然后我想回去:

  1. 为了将数据库恢复到以前的状态,我运行了flask db downgrade ---- 失败,错误为:sqlite3.OperationalError: near "DROP": syntax error
  2. 我尝试通过从User 类中删除dummy = db.Column(db.String(20)) 语句来修复错误,然后再次运行flask db downgrade ---- 再次失败并出现同样的错误。
  3. 然后我认为可能 Flask-Migrate 需要注意删除,所以我运行了flask db migrate ----成功
  4. 尝试flask db upgrade ----再次失败,出现同样的错误。

那么烧瓶迁移是如何工作的?具体来说,如何将数据库恢复到初始状态(没有dummy 属性)?

谢谢!

【问题讨论】:

    标签: flask flask-migrate


    【解决方案1】:

    SQLite 本身不支持删除或更改列(显然我猜你使用 SQLite)。这意味着 SQLite 不支持 ALTER 语句,但关系模式迁移依赖于该语句。

    要解决此问题,您必须制作一系列与新结构相对应的 SQLite 表副本,将数据从现有表转移到新表,然后删除旧表。

    幸运的是,对于 Alembic / Flask-migrate,有一个 上下文管理器 (batch_alter_table) 可以让您轻松管理所有这些更改。

    在您的情况下,解决方案是打开您的迁移脚本并在downgrade() 方法级别,将那里的指令(可能是op.drop_column('roles', 'dummy'))替换为:

    with op.batch_alter_table('roles') as batch_op:
        batch_op.drop_column('dummy')
    

    更多信息请参见this link

    一些小细节:

    • 使用迁移工具时,请始终牢记自动迁移并不总是准确的,并且可能会遗漏一些细节。应始终检查自动生成的迁移脚本。

    • 以防万一,在降级数据库时,请确保删除迁移脚本,然后生成一个新的替换它。

    【讨论】:

      【解决方案2】:

      当您运行flask db migrate 命令时,Flask migrate 会生成迁移脚本。您可以查看这些迁移文件中的命令以了解它们在做什么并确保它们在做正确的事情。事实上,它建议您在运行它们之前检查自动生成的迁移脚本。

      如果您更改了某些内容并且不重新运行migrate 命令,那么升级和降级都不会做任何不同的事情,因为它们只是在 migrate 文件夹中运行相应的迁移脚本。

      如果数据库不重要,最简单的做法是删除数据库和迁移脚本,然后再次运行flask db init,重新开始学习迁移脚本的新知识,看看是否可以升级和降级。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-24
        • 2021-02-07
        • 1970-01-01
        • 1970-01-01
        • 2020-03-15
        • 2015-02-12
        • 1970-01-01
        • 2022-08-15
        相关资源
        最近更新 更多