Skip to content

OnDeleteType Literal is missing SET DEFAULT and NO ACTION — rejects valid SQL referential actions #1836

@mahdirajaee

Description

@mahdirajaee

Description

The OnDeleteType type alias in sqlmodel/main.py (line 91) is defined as:

OnDeleteType = Literal["CASCADE", "SET NULL", "RESTRICT"]

The SQL standard defines 5 referential actions for ON DELETE / ON UPDATE:

  1. CASCADE
  2. SET NULL
  3. SET DEFAULT
  4. RESTRICT
  5. NO ACTION

SQLAlchemy's ForeignKey(ondelete=...) accepts any string and its documentation explicitly lists all 5 as valid values.

Impact

  • NO ACTION is the default behavior in PostgreSQL and most databases. Developers who want to be explicit in their schema (common in migration-driven workflows with Alembic) cannot express this without type errors.
  • SET DEFAULT is used when a foreign key column has a server_default and the parent row is deleted. This is supported by PostgreSQL, MySQL, and SQLite.

A developer hitting this gets a confusing mypy/pyright error on a perfectly valid schema definition. The only workarounds are casting to Any or dropping down to sa_column.

Fix

OnDeleteType = Literal["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"]

One-line change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions