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
- Move all op.* calls inside the body of an upgrade()/downgrade() function so they execute within an active migration context.
- In tests, use Operations(context) / op._proxy setup or the migration_context fixture to establish the proxy before calling.
- In env.py, ensure context.configure(...) and context.run_migrations() wrap any op usage.
- 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
- Keep all op.* calls inside upgrade()/downgrade() function bodies.
- In tests, establish a MigrationContext + Operations before invoking op.
- Lint for module-level op.* calls (they almost always indicate a bug).
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
- Can't drop table in batch mode
- constraint cannot be produced; original constraint is not pr
- operation is not reversible; original column is not present
- missing required positional argument: %s
- The %s method does not apply to a batch table alter operatio
AI-assisted analysis of sqlalchemy/alembic@44fb345033 (2026-08-04).
Data as JSON: /data/errors/037b52f27caec2c2.json.
Report an issue: GitHub.