sqlalchemy/alembic · error · NameError

Can't invoke function '%s', as the proxy object has not yet

Error message

Can't invoke function '%s', as the proxy object has not yet been established for the Alembic '%s' class.  Try placing this code inside a callable.

What it means

Raised as NameError by the _name_error closure inside ModuleClsProxy._create_method_proxy (langhelpers.py:130) when a module-level proxy function (e.g. alembic.op.create_table) is invoked before _install_proxy has established the per-class _proxy object. The proxy functions are generated to defer to the real Operations instance, which only exists inside a migration context; calling them outside upgrade()/downgrade() trips this guard.

Source

Thrown at alembic/util/langhelpers.py:130

            meth = getattr(cls, methname)
            if callable(meth):
                locals_[methname] = cls._create_method_proxy(
                    methname, globals_, locals_
                )
            else:
                attr_names.add(methname)

    @classmethod
    def _create_method_proxy(
        cls,
        name: str,
        globals_: MutableMapping[str, Any],
        locals_: MutableMapping[str, Any],
    ) -> Callable[..., Any]:
        fn = getattr(cls, name)

        def _name_error(name: str, from_: Exception) -> NoReturn:
            raise NameError(
                "Can't invoke function '%s', as the proxy object has "
                "not yet been "
                "established for the Alembic '%s' class.  "
                "Try placing this code inside a callable."
                % (name, cls.__name__)
            ) from from_

        globals_["_name_error"] = _name_error

        translations = getattr(fn, "_legacy_translations", [])
        if translations:
            spec = inspect_getfullargspec(fn)
            if spec[0] and spec[0][0] == "self":
                spec[0].pop(0)

            outer_args = inner_args = "*args, **kw"
            translate_str = "args, kw = _translate(%r, %r, %r, args, kw)" % (
                fn.__name__,

View on GitHub (pinned to 44fb345033)

Solutions

  1. Move all op.* calls inside the body of an upgrade()/downgrade() function so they execute within an active migration context.
  2. In tests, use Operations(context) / op._proxy setup or the migration_context fixture to establish the proxy before calling.
  3. In env.py, ensure context.configure(...) and context.run_migrations() wrap any op usage.
  4. Check that nothing imports and immediately invokes op at module top level.

Example fix

# before: op called at import time, no proxy yet
from alembic import op
op.create_table('my_table', ...)  # NameError

# after: called inside upgrade()
from alembic import op
def upgrade():
    op.create_table('my_table', ...)
Defensive patterns

Strategy: validation

Validate before calling

from alembic.operations import Operations
from alembic.runtime.migration import MigrationContext

def op_is_ready() -> bool:
    proxy = getattr(Operations, '_proxy', None)
    return proxy is not None

# in tests:
with MigrationContext.configure(connection) as ctx:
    Operations(ctx)  # installs the proxy
    assert op_is_ready()

Try / catch

# Not recommended to catch — fix the call site instead.
# If unavoidable:
try:
    op.create_table('t', sa.Column('id', sa.Integer))
except NameError as e:
    if 'proxy object has not yet been established' in str(e):
        raise RuntimeError('op called outside migration context') from e
    raise

Prevention

When it happens

Trigger: Importing alembic.op and calling op.add_column(...) at module import time or in a test without an active migration context; referencing op.* in env.py before context.begin_transaction()/run_migrations(); calling Operations methods through the module proxy without having constructed an Operations bound to a MigrationContext.

Common situations: Writing unit tests that call op functions directly; refactor that moves op calls outside the upgrade() function body; env.py that eagerly invokes op or context APIs before the migration context is configured.

Related errors


AI-assisted analysis of sqlalchemy/alembic@44fb345033 (2026-08-04). Data as JSON: /data/errors/037b52f27caec2c2.json. Report an issue: GitHub.