sqlalchemy/alembic · error · NotImplementedError

No generic 'DROP CONSTRAINT' in MySQL - please specify const

Error message

No generic 'DROP CONSTRAINT' in MySQL - please specify constraint type

What it means

MySQL has no single generic 'DROP CONSTRAINT' syntax; constraints must be dropped by type (FOREIGN KEY, PRIMARY KEY, UNIQUE, CHECK). The MariaDB/MySQL compiler handles known constraint types explicitly and raises for anything else to avoid emitting invalid SQL.

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 44fb345033)

Solutions

  1. Specify the constraint type: op.drop_constraint('t', 'name', type_='foreignkey') (or 'primary', 'unique', 'check').
  2. Use batch_alter_table, which reflects the constraint type and emits the correct MySQL DDL.
  3. For check constraints, ensure you are on MySQL 8.0+ / MariaDB which support DROP CHECK / DROP CONSTRAINT.

Example fix

// before
op.drop_constraint('orders', 'fk_orders_user')  # MySQL -> NotImplementedError
// after
op.drop_constraint('orders', 'fk_orders_user', type_='foreignkey')
Defensive patterns

Strategy: validation

Validate before calling

if dialect_name in ("mysql", "mariadb"):
    assert constraint_type in ("foreignkey", "primary", "unique", "check"), "Specify constraint type for MySQL drop_constraint"

Type guard

def is_known_mysql_constraint(type_) -> bool:
    return type_ in ("foreignkey", "primary", "unique", "check")

Prevention

When it happens

Trigger: Calling op.drop_constraint('t', 'name') without specifying a type, or passing a constraint object whose class is not ForeignKeyConstraint, PrimaryKeyConstraint, UniqueConstraint, or CheckConstraint.

Common situations: A migration generated against another dialect (PostgreSQL) that uses generic drop_constraint and is then applied to MySQL; dropping a custom constraint subclass; passing type_='check' on MySQL where only the CHECK branch is valid for MariaDB/MySQL 8+.

Related errors


AI-assisted analysis of sqlalchemy/alembic@44fb345033 (2026-08-04). Data as JSON: /data/errors/b6c122b9676d034e.json. Report an issue: GitHub.