Как отключить транзакцию DDL в миграции alembic

1

Я пытаюсь запустить транзакцию alembic. Тем не менее, все миграции выполняются в транзакции всякий раз, когда поддерживаются транзакции (см. " Выполнение миграций обновления alembic в транзакции"). Как отключить транзакцию для конкретной миграции?

Теги:
migration
sqlalchemy
alembic

1 ответ

1

Alembic имеет два режима использования транзакций:

  • Одна транзакция для всей команды миграции. Если нужно применить несколько версий, то все они выполняются в одной транзакции.
  • Используйте отдельную транзакцию для каждого шага миграции.

По умолчанию используется одна транзакции, но вы можете вызвать context.configure() в вашем env.py сценарии установить transactions_per_migration истину использовать отдельные операции.

Первая и используемая по умолчанию опция для использования одной транзакции выполняется в файле env.py который генерирует Alembic для вас, в функции run_migrations_online() в этом файле:

try:
    with context.begin_transaction():
        context.run_migrations()
finally:
    connection.close()

Вы можете просто отредактировать этот файл, чтобы удалить с with context.begin_transaction(): context manager, или использовать функцию context.get_x_argument() для переключения транзакций на основе переключателя командной строки:

try:
    # Python 3.7+
    from contextlib import nullcontext
except ImportError:
    # Earlier Python versions
    from contextlib import contextmanager
    @contextmanager
    def nullcontext():
        yield

# ...

def run_migrations_online():
    # ...
    if context.get_x_argument(as_dictionary=True).get('no-transaction', False):
        transaction_cm = nullcontext()
    else:
        transaction_cm = context.begin_transaction()
    try:
        with transaction_cm:
            context.run_migrations()
    finally:
        connection.close()

К сожалению, нелегко отключить транзакции на шаг миграции. Вам бы нужно было полностью отключить транзакции (просто не используйте context.begin_transaction() в env.py), а затем явно использовать транзакцию для каждого шага upgrade() или downgrade():

def run_migrations_online():
    # ...

    try:
        # no with context.begin_transaction() here
        context.run_migrations()
    finally:
        connection.close()

и на каждом этапе миграции:

def upgrade():
    with context.begin_transaction():
        # ### commands auto generated by Alembic - please adjust! ###
        op.create_table(
            # ...
        )
        # etc.
  • 0
    Это то, чего я боялся, было единственным решением. Спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню