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