{"record":{"id":"7652404870b74ae4","repo":"sqlalchemy/alembic","slug":"todo","errorCode":null,"errorMessage":"TODO","messagePattern":"TODO","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"alembic/operations/batch.py","lineNumber":713,"sourceCode":"                # Operations.implementation_for(alter_column)\n                return\n            raise ValueError(\"No such constraint: '%s'\" % const.name)\n        else:\n            if isinstance(const, PrimaryKeyConstraint):\n                for col in const.columns:\n                    self.columns[col.name].primary_key = False\n\n    def create_index(self, idx: Index) -> None:\n        self.new_indexes[idx.name] = idx  # type: ignore[index]\n\n    def drop_index(self, idx: Index) -> None:\n        try:\n            del self.indexes[idx.name]  # type: ignore[arg-type]\n        except KeyError:\n            raise ValueError(\"No such index: '%s'\" % idx.name)\n\n    def rename_table(self, *arg, **kw):\n        raise NotImplementedError(\"TODO\")\n","sourceCodeStart":695,"sourceCodeEnd":714,"githubUrl":"https://github.com/sqlalchemy/alembic/blob/5551b5d35f985c99cb8f1af2b3c526b050e4c059/alembic/operations/batch.py#L695-L714","documentation":"Raised as NotImplementedError('TODO') by ApplyBatchImpl.rename_table (batch.py:712-713). Renaming a table inside a batch_alter_table block is not implemented — batch mode is designed to alter the structure of one existing table, and a rename of the surrounding table is not a supported batch operation. The message is a literal placeholder indicating the feature was never built.","triggerScenarios":"Calling batch_op.rename_table('old', 'new') inside a `with op.batch_alter_table(...)` block. The ApplyBatchImpl class simply has no rename_table logic and raises immediately.","commonSituations":"Developers assume the batch proxy mirrors the full Operations API and try to combine a table rename with column alters in one batch. This is unsupported on all backends, not just SQLite.","solutions":["Perform the rename as a top-level op.rename_table('old', 'new') call, outside any batch context.","If you also need structural changes, do the rename first at top level, then open batch_alter_table against the new name.","Do not attempt to rename inside batch mode; there is no workaround."],"exampleFix":"// before\nwith op.batch_alter_table('user') as batch_op:\n    batch_op.rename_table('user', 'users')\n// after\nop.rename_table('user', 'users')\nwith op.batch_alter_table('users') as batch_op:\n    batch_op.alter_column('email', existing_type=sa.String(255))","handlingStrategy":"validation","validationCode":"# Disallow rename_table inside batch context by routing it to the top level.\ndef safe_op(op_name, *args, **kwargs):\n    if op_name == 'rename_table':\n        assert not _inside_batch, 'rename_table must run at top level, not in batch mode'\n    return getattr(op, op_name)(*args, **kwargs)\n\nop.rename_table('old', 'new')  # top-level, never inside batch","typeGuard":"from typing import Literal\nNonBatchOp = Literal['rename_table', 'create_table', 'drop_table']\ndef must_run_top_level(op_name: str) -> bool:\n    return op_name in ('rename_table', 'create_table', 'drop_table')","tryCatchPattern":null,"preventionTips":["Always call op.rename_table() outside a batch_alter_table block.","Do table renames before opening batch_alter_table against the new name.","Remember batch mode supports alters only, not DDL on the surrounding table."],"tags":["alembic","batch-mode","ddl","database-migration"],"backgroundTag":null,"analyzedSha":"5551b5d35f985c99cb8f1af2b3c526b050e4c059","analyzedAt":"2026-08-11T01:38:46.612Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}