{"id":"5c4f638b771b5e16","repo":"sqlalchemy/alembic","slug":"the-s-method-does-not-apply-to-a-batch-table-alte","errorCode":null,"errorMessage":"The %s method does not apply to a batch table alter operation.","messagePattern":"The (.+?) method does not apply to a batch table alter operation\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"alembic/operations/base.py","lineNumber":1713,"sourceCode":"\n    This basically omits the ``table_name`` and ``schema`` parameters\n    from associated methods, as these are a given when running under batch\n    mode.\n\n    .. seealso::\n\n        :meth:`.Operations.batch_alter_table`\n\n    Note that as of 0.8, most of the methods on this class are produced\n    dynamically using the :meth:`.Operations.register_operation`\n    method.\n\n    \"\"\"\n\n    impl: BatchOperationsImpl\n\n    def _noop(self, operation: Any) -> NoReturn:\n        raise NotImplementedError(\n            \"The %s method does not apply to a batch table alter operation.\"\n            % operation\n        )\n\n    if TYPE_CHECKING:\n        # START STUB FUNCTIONS: batch_op\n        # ### the following stubs are generated by tools/write_pyi.py ###\n        # ### do not edit ###\n\n        def add_column(\n            self,\n            column: Column[Any],\n            *,\n            insert_before: str | None = None,\n            insert_after: str | None = None,\n            if_not_exists: bool | None = None,\n            inline_references: bool | None = None,\n            inline_primary_key: bool | None = None,","sourceCodeStart":1695,"sourceCodeEnd":1731,"githubUrl":"https://github.com/sqlalchemy/alembic/blob/44fb3450330204b222ff05135e1fbbbdb28c44db/alembic/operations/base.py#L1695-L1731","documentation":"BatchOperations is a narrowed view of Operations scoped to a single table being altered via batch_alter_table. Methods that operate at the schema level (create_table, drop_table, create_index on an unrelated table, etc.) are mapped to _noop, which raises because they are meaningless inside a batch context where the target table is fixed.","triggerScenarios":"Inside a 'with op.batch_alter_table(\"t\") as batch_op:' block, calling one of the schema-level methods that are explicitly registered to _noop (commonly batch_op.create_table(...) or batch_op.drop_table(...)).","commonSituations":"Autogenerated batch block that accidentally included a create_table; a developer assuming batch_op mirrors the full Operations API; copy-pasting an op.create_table call and renaming op to batch_op.","solutions":["Move create_table/drop_table outside the batch_alter_table context and call them on op directly.","If you need to fully redefine the table, use batch_alter_table(recreate='always') and add columns/constraints via batch_op.add_column / create_*_constraint.","Check the BatchOperations stub list to see which methods are valid inside batch mode."],"exampleFix":"// before\nwith op.batch_alter_table('users') as batch_op:\n    batch_op.create_table(sa.table('extra', sa.column('id', sa.Integer)))\n// after\nop.create_table('extra', sa.Column('id', sa.Integer))\nwith op.batch_alter_table('users') as batch_op:\n    batch_op.add_column(sa.Column('name', sa.String))","handlingStrategy":"type-guard","validationCode":"from alembic.operations.base import BatchOperations\nif isinstance(op_or_batch, BatchOperations):\n    raise RuntimeError(\"Schema-level ops not allowed inside batch_alter_table; call on op instead\")","typeGuard":"def is_batch_op(obj) -> bool:\n    from alembic.operations.base import BatchOperations\n    return isinstance(obj, BatchOperations)","tryCatchPattern":null,"preventionTips":["Only call column/constraint/index methods on batch_op; call table-level ops on op.","Review autogenerated migrations for misplaced create_table inside batch blocks.","Lint for batch_op.create_table / batch_op.drop_table."],"tags":["batch-mode","operations","no-op"],"analyzedSha":"44fb3450330204b222ff05135e1fbbbdb28c44db","analyzedAt":"2026-08-04T19:57:10.248Z","schemaVersion":2}