【问题标题】:Local and heroku db get out of sync while migrating using alembic使用 alembic 迁移时,本地和 heroku db 不同步
【发布时间】:2014-01-22 03:26:37
【问题描述】:

我正在使用托管在 heroku 上的 Flask 和 Angular 构建一个应用程序。我在迁移 heroku postgresql 时遇到问题。我正在使用flask-migrate,它是alembic 的一个小包装。本地一切都很好。当我运行 heroku run upgrade 时出现异常,它运行 alembic upgrade 命令。

INFO  [alembic.migration] Context impl PostgresqlImpl.
INFO  [alembic.migration] Will assume transactional DDL.
INFO  [alembic.migration] Running upgrade None -> 19aeffe4063d, empty message
Traceback (most recent call last):
  File "manage.py", line 13, in <module>
    manager.run()
...

   cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (ProgrammingError) relation "users" already exists
 '\nCREATE TABLE users (\n\tid SERIAL NOT NULL, \n\tusername VARCHAR(32), \n\tpassword_hash VARCHAR(128), \n\tPRIMARY KEY (id)\n)\n\n' {}

简单地说,alembic 正在尝试从创建数据库的第一个迁移中运行。我尝试使用heroku run python manage.py db upgrade +2 或修订号明确设置正确的修订版,但例外情况相同。

lukas$ heroku run python manage.py db current
Running `python manage.py db current` attached to terminal... up, run.1401
INFO  [alembic.migration] Context impl PostgresqlImpl.
INFO  [alembic.migration] Will assume transactional DDL.
Current revision for postgres://...: None

我的猜测是,由于 Heroku 修订版的临时文件系统未存储,但如果我明确设置修订版,这应该不是问题,对吧? :)

如何设置当前的修订头?

这里是相关代码:

过程文件:

web: gunicorn server:app
init: python manage.py db init
upgrade: python manage.py db upgrade

models.py

db = SQLAlchemy()

ROLE_USER = 0
ROLE_ADMIN = 1


class User(db.Model):
  __tablename__ = "users"
  id = db.Column(db.Integer, primary_key = True)
  username = db.Column(db.String(32), unique = True, index = True)
  email = db.Column(db.String(255), unique = True)
  password_hash = db.Column(db.String(128))
  role = db.Column(db.SmallInteger, default = ROLE_USER)

【问题讨论】:

  • 不确定这是否是实际问题,但是当您转到 heroku 时,您不需要使用init,因为这是创建新存储库的命令。您需要做的就是升级命令。

标签: python sqlalchemy migration flask alembic


【解决方案1】:

您在Procfile 中输入的init 命令会创建一个全新的Alembic 存储库,您只需在开发机器上执行一次。当您部署到新机器时,您只需运行upgrade 命令即可创建数据库并将其更新到最新版本。

Alembic 和 Flask-Migrate 有一个名为 stamp 的命令可以帮助您解决此问题。使用stamp,您可以告诉Alembic 将您选择的修订版写入数据库,而无需触及数据库本身。

例如,如果 Alembic 必须一一完成所有迁移,则在有大量迁移时从头开始创建数据库可能需要很长时间。相反,您可以使用 db.create_all() 创建数据库,然后运行:

$ ./manage.py db stamp HEAD

这样数据库就被标记为已更新。

另外,在某些时候,我赞成将维护命令放在Procfile 中的想法,但这些天我只把服务放在那里,所以我只会把web 留在那里。要升级数据库,我认为显式运行命令更可预测:

$ heroku run python manage.py db upgrade

【讨论】:

  • 非常感谢邮票的帮助。你知道当前头部存储在哪里吗?
  • 是的,Alembic 会在您的数据库中添加一个小表来写入其状态。
猜你喜欢
  • 1970-01-01
  • 2013-02-01
  • 2011-10-05
  • 1970-01-01
  • 2013-03-20
  • 2015-01-31
  • 2022-11-10
相关资源
最近更新 更多