-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
Proposed Changes
There are several instances in NetBox where we define two UniqueConstraints to handle nullable fields: One to handle null values, and one to handle non-null values. The Region model is one example. The UniqueConstraints defined below ensure that the name
field is unique to its parent, if one is assigned, or otherwise unique to regions having no parent:
class Meta:
constraints = (
# Has no effect if parent is NULL, because PostgreSQL considers NULL != NULL
models.UniqueConstraint(
fields=('parent', 'name'),
name='%(app_label)s_%(class)s_parent_name'
),
# Checks that name is unique if parent is NULL
models.UniqueConstraint(
fields=('name',),
name='%(app_label)s_%(class)s_name',
condition=Q(parent__isnull=True),
violation_error_message=_("A top-level region with this name already exists.")
),
...
)
PostgreSQL 15 introduced support for declaring NULLS NOT DISTINCT
on unique indexes, allowing for the two above constraints to be condensed into one by setting nulls_distinct=False
:
class Meta:
constraints = (
models.UniqueConstraint(
fields=('parent', 'name'),
name='%(app_label)s_%(class)s_parent_name',
nulls_distinct=False, # Assert that NULL == NULL
),
...
)
NOTE: This is not supported on PostgreSQL versions earlier than 15.
Justification
This will reduce the overall number of unique constraints we have defined, and greatly simplify the logic for ensuring uniqueness where nullable fields must be considered.