【发布时间】:2019-05-07 05:14:06
【问题描述】:
我对 Flask 有一些经验,但对数据库(Flask-migrate / alembic / SqlAlchemy)不太了解。
我正在关注this 教程,一切正常。
我有一个这样的用户模型:
# user_model.py
from app import DB
... other imports
class User(UserMixin, DB.Model):
__tablename__ = 'users'
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))
然后我可以初始化数据库、进行迁移、升级等。
当我想更改 id 属性时,问题就开始了,这在 Python 中不是一个很好的变量名选择。假设我想将其重命名为 user_id。
现在显然数据库已经存在并且里面有一些数据。我想也许通过 Flask-Migrate/Alembic 的某种魔法,仅仅修改 User 类就可以了。那就是把上面的 id 行改成:
user_id = DB.Column(DB.Integer, primary_key=True)
如果我这样做并运行flask db migrate,我会得到:
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected added column 'users.user_id'
INFO [alembic.autogenerate.compare] Detected removed column 'users.id'
所以实际上 Alembic 将其检测为删除了一个列并添加了一个新列,我认为这是有道理的。
但如果我运行flask db upgrade,这实际上不起作用。我收到以下错误:
错误 [alembic.env] (sqlite3.OperationalError) 无法添加 NOT NULL 默认值为 NULL 的列 [SQL: 'ALTER TABLE users ADD COLUMN user_id INTEGER NOT NULL']
错误很明显。关键是我不想添加新列,我只想重命名现有列。
环顾四周,我也尝试将处理升级的script.py修改为使用alter_column方法:
def upgrade():
${upgrades if upgrades else "pass"}
# just added this line below
op.alter_column('users', 'id', nullable=False, new_column_name='user_id')
但是这似乎也不起作用(我得到与上面相同的错误)。
所以问题归结为一个非常简单的问题:如何使用 Flask-Migrate 重命名 Flask 应用程序中的数据库列?或者换句话说,如果我想修改给定模型的属性,我必须做什么才能正确重命名数据库中的相应列名?
【问题讨论】:
标签: python-3.x flask flask-sqlalchemy alembic flask-migrate