sqlalchemy/alembic · error · NotImplementedError
No generic 'DROP CONSTRAINT' in MySQL - please specify…
Error message
No generic 'DROP CONSTRAINT' in MySQL - please specify constraint type
What it means
MySQL/MariaDB DropConstraint compilation raises NotImplementedError when the constraint being dropped is not a ForeignKeyConstraint, PrimaryKeyConstraint, UniqueConstraint, or CheckConstraint. MySQL has no generic DROP CONSTRAINT syntax; each constraint type has its own DROP FOREIGN KEY / DROP PRIMARY KEY / DROP INDEX / DROP CHECK statement, so Alembic needs a typed constraint.
Solutions
- Drop a typed constraint: use op.drop_constraint with a ForeignKeyConstraint, PrimaryKeyConstraint, UniqueConstraint, or CheckConstraint.
- For foreign keys, use 'foreignkey' type via op.drop_constraint('name', 't', type_='foreignkey').
- For check constraints on MariaDB/MySQL, ensure the constraint is a CheckConstraint so DROP CHECK / DROP CONSTRAINT is emitted.
Example fix
# before (ambiguous)
op.drop_constraint('my_constraint', 'my_table')
# after (specify type)
op.drop_constraint('my_fk', 'my_table', type_='foreignkey') Defensive patterns
Strategy: validation
Validate before calling
VALID_TYPES = {'foreignkey', 'primary', 'unique', 'check'}
def safe_drop_constraint(op, name, table, type_=None):
if type_ not in VALID_TYPES:
raise ValueError(f'specify type_ in {VALID_TYPES}')
op.drop_constraint(name, table, type_=type_) Type guard
def is_known_constraint_type(t: str | None) -> bool:
return t in {'foreignkey', 'primary', 'unique', 'check'} Prevention
- Always pass the type_ argument to op.drop_constraint on MySQL/MariaDB.
- Avoid constructing generic schema.DropConstraint with a bare Constraint subclass.
- Test constraint drops against the target dialect in CI.
When it happens
Trigger: Calling op.drop_constraint() with a generic/anonymous Constraint object, or a custom Constraint subclass not recognized by the MySQL dispatch; dropping a constraint whose type is ambiguous.
Common situations: Custom constraint classes; code that constructs schema.DropConstraint with a bare Constraint(name=...) lacking a concrete subclass; migrating from another dialect where generic DROP CONSTRAINT worked.
Related errors
- Individual alter column constructs not supported by MySQL
- No support for ALTER of constraints in SQLite dialect…
- Can't create table in batch mode
- Can't send params and multiparams at the same time
- Cannot call run_async with a sync engine
AI-assisted analysis of sqlalchemy/alembic@5551b5d35f (2026-08-11).
Data as JSON: /api/errors/b6c122b9676d034e.
Report an issue: GitHub.
Appendix: source
Thrown at alembic/ddl/mysql.py:553
):
assert not kw
return compiler.visit_drop_constraint(element)
elif isinstance(constraint, schema.CheckConstraint):
# note that SQLAlchemy as of 1.2 does not yet support
# DROP CONSTRAINT for MySQL/MariaDB, so we implement fully
# here.
if compiler.dialect.is_mariadb:
return "ALTER TABLE %s DROP CONSTRAINT %s" % (
compiler.preparer.format_table(constraint.table),
compiler.preparer.format_constraint(constraint),
)
else:
return "ALTER TABLE %s DROP CHECK %s" % (
compiler.preparer.format_table(constraint.table),
compiler.preparer.format_constraint(constraint),
)
else:
raise NotImplementedError(
"No generic 'DROP CONSTRAINT' in MySQL - "
"please specify constraint type"
)
View on GitHub (pinned to 5551b5d35f)