Как использовать SQLAlchemy Utils в модели SQLAlchemy
Я пытаюсь создать пользовательскую модель, которая использует UUID в качестве первичного ключа:
from src.db import db # SQLAlchemy instance
import sqlalchemy_utils
import uuid
class User(db.Model):
__tablename__ = 'user'
id = db.Column(sqlalchemy_utils.UUIDType(binary=True), primary_key=True, nullable=False)
Но когда я генерирую миграции, я получаю:
File "/home/pc/Downloads/project/auth/venv/lib/python3.6/site-packages/alembic/runtime/environment.py", line 836, in run_migrations
self.get_context().run_migrations(**kw)
File "/home/pc/Downloads/project/auth/venv/lib/python3.6/site-packages/alembic/runtime/migration.py", line 330, in run_migrations
step.migration_fn(**kw)
File "/home/pc/Downloads/project/auth/migrations/versions/efae4166f832_.py", line 22, in upgrade
sa.Column('id', sqlalchemy_utils.types.uuid.UUIDType(length=16), nullable=False),
NameError: name 'sqlalchemy_utils' is not defined`
Я попытался подробно проинформировать модуль, который я использую, как это, и использовать "внутреннюю" реализацию, которая SQLAlchemy
Obs: если я вручную импортирую sqlalchemy_utils
в /migrations/version/efae4166f832_.py
и удалить длину, которая генерируется автоматически sa.Column('id', sqlalchemy_utils.types.uuid.UUIDType(length=16), nullable=False)
работает нормально
Я генерирую миграции, используя generate.py
сценарий:
from src import create_app
from src.db import db
from flask_migrate import Migrate
# Models
from src.user.models.user import User
app = create_app()
migrate = Migrate(app, db)`
Obs: движок MySQL
Я ожидаю, что когда я генерирую миграцию, она генерирует пользовательскую модель, которая использует UUID, реализованный из SQLAlchemy Utils в качестве первичного ключа.
7 ответов
Спасибо, Марко, но я уже исправил это. Я поставил импорт import sqlalchemy_utils
внутри env.py и script.py.mako я также поместил следующую функцию:
def render_item(type_, obj, autogen_context):
"""Apply custom rendering for selected items"""
if type_ == "type" and isinstance(obj, sqlalchemy_utils.types.uuid.UUIDType):
# Add import for this type
autogen_context.imports.add("import sqlalchemy_utils")
autogen_context.imports.add("import uuid")
return "sqlalchemy_utils.types.uuid.UUIDType(), default=uuid.uuid4"
# Default rendering for other objects
return False
Внутри env.py и в том же файле я установил render_item=render_item
в функции run_migrations_online
:
context.configure(
...,
render_item=render_item,
...
)
Я попытался сделать это автоматически, но не смог найти ничего, что могло бы мне помочь.
Порядок операций имеет значение:
export FLASK_APP=manage.py
flask db init
Сделать учебник выше
flask db migrate
flask db upgrade
Вы просто должны добавить:
import sqlalchemy_utils
в ваш script.py.mako внутри папки миграций
Фон
Было бы идеально, если бы вам не приходилось вручную редактировать каждый файл миграции с оператором.
Глядя на документацию Alembic , это «файл шаблона Mako, который используется для создания новых сценариев миграции». Таким образом, вам потребуется повторно сгенерировать файлы миграции, при этом Mako уже импортирует sqlalchemy_utils как часть создания файла миграции.
Исправить
Если возможно, удалите свои старые миграции (они, вероятно, все равно сломаны) и добавьтеimport sqlalchemy_utils
как так к твоемуscript.py.mako
файл:
from alembic import op
import sqlalchemy as sa
import sqlalchemy_utils #<-- line you add
${imports if imports else ""}
затем просто перезапустите ваши перегонные миграции:
alembic revision --autogenerate -m "create initial tables"
когда вы посмотрите на свой файл миграции, вы должны увидетьsqlalchemy_utils
уже импортированы через скрипт mako.
надеюсь, это поможет.
Добавление
import sqlalchemy_utils
в
script.py.mako
file автоматически импортирует эту строку во все созданные файлы миграции и решит проблему.
from alembic import op
import sqlalchemy as sa
import sqlalchemy_utils
${imports if imports else ""}
Добавить import sqlalchemy_utils
линия к вновь созданному migrations/versions/{hash}_my_comment.py
файл. Однако это решит проблему только на этом конкретном этапе миграции. Если вы ожидаете, что внесете множество изменений в столбцы, ссылки на которые sqlalchemy_utils
Вы, вероятно, должны сделать что-то более надежное, как предложение Уолтера. Даже тогда, похоже, вам может понадобиться добавить код, чтобы правильно обрабатывать каждый тип столбца, который вы в конечном итоге используете.
NB. Несмотря на то, что в нескольких местах вы видите предложение о добавлении строки импорта в script.py.mako
файл, который не работал для меня.
Перед бегомflask db upgrade
вам необходимо проверить файл версии миграции. В этом случае я использую sqlalchemy_utils для своих моделей приложений.
Поэтому просто импортируйте sqlalchemy_utils, чтобы исправить это:
import sqlalchemy_utils
Если вы хотите, чтобы типы перечислений распознавались перегонным кубом, сделайте следующее.
Монтаж
pip install alembic-postgresql-enum or poetry add alembic-postgresql-enum
Добавьте импорт в envy.py
import alembic_postgresql_enum
миграции будут генерироваться автоматически.
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.sync_enum_values('public', 'channel', ['USSD', 'WHATSAPP'],
[('subscription', 'channel')],
enum_values_to_rename=[])
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.sync_enum_values('public', 'channel', ['WHATSAPP'],
[('subscription', 'channel')],
enum_values_to_rename=[])
# ### end Alembic commands ###
Подробнее о пакете можно прочитать здесь