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),
...