Django postgres генерация уникальных имен ограничений

При добавлении нового уникального ограничения в модель django автоматически создается имя для этого ограничения в postgres. Postgres генерирует это имя или Django? Является ли оно детерминированным?

например, я использую эту модель

class MyModel(Model):
  field1 = TextField()
  field2 = IntegerField()

  class Meta:
    unique_together = ("field1", "field2")

Я получил имя ограничения с

select constraint_name
from information_schema.constraint_column_usage
where table_name = 'myapp_mytable'

Я получаю имя типа field1_field2_d04755de_uniq

Как предложил @willem-van-onsem, использование UniqueConstraint позволяет задать имя ограничения (которое довольно детерминировано)

Django определит это имя. Действительно, исходный код [GitHub] показывает, что он определяет имя с помощью:

if name is None:
    name = IndexName(table, columns, "_uniq", create_unique_name)

IndexName [GitHub] будет вызывать create_unique_name с table, columns и suffix:

class IndexName(TableColumns):
    
    def __init__(self, table, columns, suffix, create_index_name):
        # …
        pass

    def __str__(self):
        return self.create_index_name(self.table, self.columns, self.suffix)

и create_unique_name вернет процитированную версию _create_index_name, которая составит дайджест из table_name и column_names [GitHub]:

def _create_index_name(self, table_name, column_names, suffix=""):
    # …
    _, table_name = split_identifier(table_name)
    hash_suffix_part = "%s%s" % (
        names_digest(table_name, *column_names, length=8),
        suffix,
    )
    # …

Но использование unique_together, скорее всего, будет устаревшим. Действительно, в документации по unique_together говорится:

Используйте UniqueConstraint с constraints вместо этого.

UniqueConstraint обеспечивает большую функциональность, чем unique_together. unique_together может быть устаревшим в будущем.

Вы можете определить это UniqueConstraint где вы также можете вручную указать имя ограничения:

from django.db import models

class MyModel(models.Model):
    field1 = models.TextField()
    field2 = models.IntegerField()

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=('field1', 'field2'), name='some_constraint_name')
        ]

Я просто добавляю это в миграции:

...
        migrations.RunSQL("""
            ALTER TABLE IF EXISTS public.api_sectoraltr
                ADD UNIQUE (year, category_id, code_id);
        """, reverse_sql=migrations.RunSQL.noop),
...
Вернуться на верх