Flask-migrate: изменить атрибуты модели и переименовать соответствующие столбцы базы данных - PullRequest
1 голос
/ 07 мая 2019

У меня есть небольшой опыт работы с Flask, но не очень много с базами данных (Flask-migrate / alembic / SqlAlchemy).

Я следую этому учебнику, и все работает хорошо.

У меня есть такая модель пользователя:

# 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 пользователи 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 с помощью Flask-Migrate?Или, другими словами, если я хочу изменить атрибуты данной модели, что мне нужно сделать, чтобы имена соответствующих столбцов в базе данных были правильно переименованы?

1 Ответ

0 голосов
/ 07 мая 2019

Чтобы просто переименовать столбец в скрипте alembic (который аналогичен flash-migrate), вы должны сделать правильно:

op.alter_column('users', 'id', nullable=False, new_column_name='user_id')

Проблема, на мой взгляд, в том, что вам нужнотакже для изменения ограничения в качестве первичного ключа:

op.drop_constraint('user_pkey', 'users', type_='primarykey')
op.create_primary_key('user_pkey', 'users', ['user_id'])

Возможно, вам потребуется изменить имя воссозданного первичного ключа в зависимости от типа вашей базы данных (у меня это работает с PostgreSQL)

Сгенерированные автоматически алембические сценарии всегда должны просматриваться, довольно часто они не делают того, что мы хотим, если бы не простые изменения.

Примечание: Если использовался ваш столбец idв качестве внешнего ключа вы также можете изменить ограничения внешнего ключа в других таблицах.

Изменить первичный ключ в Alembic описывает такую ​​же проблему.

...