sqlalchemy/alembic · error · ValueError
recreate may be one of 'auto', 'always', or 'never'.
Error message
recreate may be one of 'auto', 'always', or 'never'.
What it means
BatchOperationsImpl.__init__ raises ValueError when the recreate parameter of batch_alter_table() is not one of 'auto', 'always', or 'never'. The value controls whether the table is rebuilt via copy-and-move: 'auto' decides based on the operation, 'always' forces a rebuild, 'never' forbids it (erroring if the operation requires one).
Solutions
- Use recreate='auto' (default) to let Alembic decide based on the dialect and operations.
- Use recreate='always' to force a table rebuild (needed for SQLite and some constrained operations).
- Use recreate='never' to forbid rebuilds (only valid on dialects supporting the needed ALTERs natively).
Example fix
# before
with op.batch_alter_table('t', recreate=True) as batch_op:
...
# after
with op.batch_alter_table('t', recreate='always') as batch_op:
... Defensive patterns
Strategy: validation
Validate before calling
VALID_RECREATE = {'auto', 'always', 'never'}
def safe_batch(op, table, recreate='auto', **kw):
if recreate not in VALID_RECREATE:
raise ValueError(f"recreate must be one of {VALID_RECREATE}")
return op.batch_alter_table(table, recreate=recreate, **kw) Type guard
def is_valid_recreate(value: str) -> bool:
return value in {'auto', 'always', 'never'} Prevention
- Pass only 'auto', 'always', or 'never' as recreate.
- Do not pass booleans; use 'always'/'never' strings.
- Default to 'auto' unless you have a specific reason to force or forbid a rebuild.
When it happens
Trigger: Calling op.batch_alter_table('t', recreate='sometimes') or passing a typo/boolean/None as recreate.
Common situations: Typos in the recreate value; passing recreate=True instead of recreate='always'; outdated tutorial using an invalid string.
Related errors
- Can't create table in batch mode
- No support for ALTER of constraints in SQLite dialect…
- The method does not apply to a batch table alter operation.
- TODO
- A plugin named is already registered
AI-assisted analysis of sqlalchemy/alembic@5551b5d35f (2026-08-11).
Data as JSON: /api/errors/07d0fa549eee11bd.
Report an issue: GitHub.
Appendix: source
Thrown at alembic/operations/batch.py:68
def __init__(
self,
operations,
table_name,
schema,
recreate,
copy_from,
table_args,
table_kwargs,
reflect_args,
reflect_kwargs,
naming_convention,
partial_reordering,
):
self.operations = operations
self.table_name = table_name
self.schema = schema
if recreate not in ("auto", "always", "never"):
raise ValueError(
"recreate may be one of 'auto', 'always', or 'never'."
)
self.recreate = recreate
self.copy_from = copy_from
self.table_args = table_args
self.table_kwargs = dict(table_kwargs)
self.reflect_args = reflect_args
self.reflect_kwargs = dict(reflect_kwargs)
self.reflect_kwargs.setdefault(
"listeners", list(self.reflect_kwargs.get("listeners", ()))
)
self.reflect_kwargs["listeners"].append(
("column_reflect", operations.impl.autogen_column_reflect)
)
self.naming_convention = naming_convention
self.partial_reordering = partial_reordering
self.batch = []
View on GitHub (pinned to 5551b5d35f)