Как отключить транзакцию DDL в миграции alembic - PullRequest
0 голосов
/ 06 декабря 2018

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

1 Ответ

0 голосов
/ 05 февраля 2019

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

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

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

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

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

Вы можете просто отредактировать этот файл, чтобы удалить менеджер контекста with context.begin_transaction():, или использовать 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.
...