Использование self.id в другом поле с одним запросом - PullRequest
1 голос
/ 23 января 2012

По общему признанию, это очень похоже на этот , который я задавал ранее, однако, было бы очень хорошо иметь ответ на него.

Я хочу создать экземпляр, используя первичный ключ для заполнения другого поля. Юджи Томита предложил решение с использованием двух запросов (что, кстати, работает отлично), но я хочу знать, возможно ли это сделать, используя только один запрос.

Решение Юджи Томиты:

def save(self, *args, **kwargs):
    add = not self.pk
    super(MyModel, self).save(*args, **kwargs)
    if add:
        self.identification = str(self.id)
        kwargs['force_insert'] = False # create() uses this, which causes error.
        super(MyModel, self).save(*args, **kwargs)

Заранее спасибо.

1 Ответ

0 голосов
/ 23 января 2012

Если ваш первичный ключ представляет собой автоматически увеличивающееся целое число, вы можете вычислить следующий ключ, запустив SELECT MAX(id) FROM myTable из оболочки db;или в django:

from django.db.models import Max
next_key = MyTable.objects.aggregate(next=Max('id'))['next']+1

Проблема с этим подходом состоит в том, что вы должны реализовать блокировку строки;в противном случае другой процесс может добавить в базу данных - получение следующего значения идентификатора, в результате чего ваш код выдаст исключение IntegrityError;и это не решает проблему «двух запросов».

Лучшее решение - использовать непоследовательные первичные ключи.Обычно это UUID .В MySQL вы можете использовать функцию UUID() в качестве основного ключа.Это гарантирует (разумно) отсутствие коллизий и уникальность.

В Django нет официальной поддержки полей UUID (отправлено patch ), но есть лотов из примеров , которые вы можете использовать.

Если вы пойдете по этому маршруту, вы можете в любой момент сгенерировать первичный ключ и затем присвоить его модели безвыполнение запроса.

...