Skip to content

feat(indexes): add nulls_not_distinct option to PostgreSQLIndex - #2247

Open
pctablet505 wants to merge 3 commits into
tortoise:developfrom
pctablet505:fix-1641-nulls-not-distinct
Open

feat(indexes): add nulls_not_distinct option to PostgreSQLIndex#2247
pctablet505 wants to merge 3 commits into
tortoise:developfrom
pctablet505:fix-1641-nulls-not-distinct

Conversation

@pctablet505

@pctablet505 pctablet505 commented Jul 15, 2026

Copy link
Copy Markdown

Fixes #1641.

Adds unique and nulls_not_distinct parameters to PostgreSQLIndex, so users can create NULLS NOT DISTINCT unique indexes directly instead of relying on unique_together. This matches the approach discussed in the issue: keep unique_together unchanged and expose the option on the PostgreSQL-specific index class.

Adds regression tests for schema generation and migration SQL output.

@pctablet505
pctablet505 marked this pull request as ready for review July 17, 2026 12:48
@codspeed-hq

codspeed-hq Bot commented Jul 26, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 24 untouched benchmarks


Comparing pctablet505:fix-1641-nulls-not-distinct (7f13df6) with develop (8c12adc)

Open in CodSpeed

Add unique and nulls_not_distinct parameters to PostgreSQLIndex so users
can create PostgreSQL unique indexes that treat NULL values as equal.
This implements the direction from abondar in tortoise#1641: expose the option
on tortoise.contrib.postgres.indexes.PostgreSQLIndex instead of changing
unique_together behavior.

Fixes tortoise#1641
Run make style to satisfy the ruff format and isort (I) checks so the
lint gate passes.
…ex_sql

add_index() unconditionally passes unique= and nulls_not_distinct= to
self._get_index_sql(), but only the Postgres schema editor's override
declared those parameters. Every other backend (sqlite/mssql via the
base implementation, and mysql via its own override) raised
TypeError: _get_index_sql() got an unexpected keyword argument 'unique'
on any migration that adds an index — this broke test_add_index_operation_runs_sql
on the sqlite/mysql/mssql CI matrix.

Both parameters are now accepted on every backend. unique mirrors the
existing UNIQUE_INDEX_CREATE_TEMPLATE/uidx-prefix pattern already used
elsewhere in these classes; nulls_not_distinct is inherently
PostgreSQL-only (NULLS NOT DISTINCT has no equivalent elsewhere) so it's
accepted and ignored on other backends, same as unique already is today
in practice (only PostgreSQLIndex sets these attributes).

Also fixes the mypy error in BasePostgresSchemaEditor._get_index_sql:
_generate_index_name expects list[str], not the Sequence[str] the
field_names parameter is typed as.
@pctablet505
pctablet505 force-pushed the fix-1641-nulls-not-distinct branch from 9603f3e to 660a1e7 Compare August 21, 2026 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

unique indexes (for unique_together) on nullable columns need to be optionable for nulls not distinct

1 participant