alembic icon indicating copy to clipboard operation
alembic copied to clipboard

Example change for branched connection still doesn't work

Open RazerM opened this issue 2 years ago • 3 comments

Describe the bug From https://alembic.sqlalchemy.org/en/latest/cookbook.html#sharing-a-connection-with-a-series-of-migration-commands-and-environments there is this snippet:

def run_migrations_online():
    connectable = config.attributes.get('connection', None)

    if connectable is None:
        # only create Engine if we don't have a Connection
        # from the outside
        connectable = engine_from_config(
            config.get_section(config.config_ini_section),
            prefix='sqlalchemy.',
            poolclass=pool.NullPool)

    context.configure(
        connection=connectable,
        target_metadata=target_metadata
    )

    with context.begin_transaction():
        context.run_migrations()

but connectable is then an engine when there isn't one in the config. The error is:

'connection' argument to configure() is expected to be a sqlalchemy.engine.Connection instance, got Engine(postgresql://pydiscos3test:***@postgres/discos3)

Versions.

  • OS: N/A
  • Python: 3.7
  • Alembic: 1.7.3
  • SQLAlchemy: 1.4.23
  • Database: PostgreSQL
  • DBAPI:

Additional context

Have a nice day!

RazerM avatar Sep 17 '21 17:09 RazerM

sure. can you assist with an update? I believe we can make this smooth using https://docs.python.org/3/library/contextlib.html#contextlib.closing :

import contextlib

def run_migrations_online():
    connectable = config.attributes.get('connection', None)

    if connectable is None:
        # only create Engine if we don't have a Connection
        # from the outside
        connectable = engine_from_config(
            config.get_section(config.config_ini_section),
            prefix='sqlalchemy.',
            poolclass=pool.NullPool).connect()
    else:
        connectable = contextlib.closing(connectable)

    with connectable:
        context.configure(
            connection=connectable,
            target_metadata=target_metadata
        )

        with context.begin_transaction():
            context.run_migrations()

zzzeek avatar Sep 17 '21 17:09 zzzeek

Wouldn't it need to call .begin() on the result from engine_from_config?

RazerM avatar Sep 20 '21 08:09 RazerM

context.begin_transaction() should do that

it goes here: https://github.com/sqlalchemy/alembic/blob/master/alembic/runtime/migration.py#L437 then here: https://github.com/sqlalchemy/alembic/blob/master/alembic/util/sqla_compat.py#L114

so it is approximating some of "branched" there

zzzeek avatar Sep 20 '21 17:09 zzzeek