Запретить автоматическую миграцию alembic при отсутствии изменений в схеме - PullRequest
0 голосов
/ 23 декабря 2019

Я работаю над приложением фляги и использую Flask-Migrate с базой данных снежинок через разъем Snowke-sqlalchemy .

У меня есть следующие модели вmy app / models.py:

class User(db.Model):
    username = db.Column(db.String(100), primary_key=True)


class UserActions(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user = db.Column(db.String(100), db.ForeignKey('user.username'))

Как видите, это простой пример из двух таблиц с одной таблицей с ограничением внешнего ключа.

При первом запуске flask db migrate, Я получаю следующую автоматически сгенерированную миграцию:

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('user',
    sa.Column('username', sa.String(length=100), nullable=False),
    sa.PrimaryKeyConstraint('username', name=op.f('pk_user'))
    )
    op.create_table('user_actions',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('user', sa.String(length=100), nullable=True),
    sa.ForeignKeyConstraint(['user'], ['user.username'], name=op.f('fk_user_actions_user_user')),
    sa.PrimaryKeyConstraint('id', name=op.f('pk_user_actions'))
    )
    # ### end Alembic commands ###

, которая выглядит великолепно и работает, как и ожидалось, при выполнении flask db upgrade.

Но когда я запускаю flask db migrate во второй раз, даже еслинет никаких изменений в схеме, она производит другую миграцию

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint('fk_user_actions_user_user', 'user_actions', type_='foreignkey')
    op.create_foreign_key(op.f('fk_user_actions_user_user'), 'user_actions', 'user', ['user'], ['username'])
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint(op.f('fk_user_actions_user_user'), 'user_actions', type_='foreignkey')
    op.create_foreign_key('fk_user_actions_user_user', 'user_actions', 'user', ['user'], ['username'], referent_schema='{my-schema}')
    # ### end Alembic commands ###

Я пробовал различные параметры конфигурации для metadata, привязанного к объекту flask db, но я всегда получаю эту избыточную миграцию при использовании alembicфункция автогенерации. Даже если я выполню обновление с использованием этой избыточной миграции, я получу еще один дубликат при повторном запуске flask db migrate. В моей строке подключения к БД есть схема, потому что снежинка жалуется иначе:

SQLALCHEMY_DATABASE_URI='snowflake://<my_login_name>:<password>@<account_name>/<database_name>/<schema_name>?warehouse=<warehouse_name>?role=<role_name>'

Что здесь происходит? Почему избыточная миграция производится каждый раз, даже если в схему не вносятся изменения? Я прочитал эту ссылку , но это мне не помогло. Я не указываю схему ни в одной из моделей или сценариев миграции, только в URL-адресе соединения.

1 Ответ

0 голосов
/ 23 декабря 2019

Я отвечу на мой вопрос для людей, которые будут обсуждать это в будущем:

Похоже, проблема в том, как снежинка-sqlalchemy устанавливает имя схемы для внешних ключей. Он назначает имя схемы, используемое в строке соединения с БД, и поэтому существующие внешние ключи связаны с этой схемой. Однако сравниваемые внешние ключи метаданных не имеют явной схемы (поскольку классы моделей не определяют ее), и при сравнении этих двух элементов alembic замечает разницу в именах схем. Я объяснил возможное решение проблемы здесь, но не уверен, что есть более чистый способ: https://github.com/snowflakedb/snowflake-sqlalchemy/issues/145

...