Создание объекта Django и последовательности Postgres - PullRequest
6 голосов
/ 18 января 2010

У меня есть скрипт импорта, который запускает серию команд для передачи данных из одной БД Postgres в другую, обе из которых работают с одной и той же кодовой базой Django. По большей части он использует ./manage.py loaddata для копирования, но некоторые объекты требуют дополнительной обработки, и я использую метод objects.create () Django в пользовательском сценарии для копирования данных. При этом я указываю идентификатор, т.е.

MyObject.objects.create(id = 2, title = 'foo')

Как только скрипт завершен, я замечаю, что Postgres SEQUENCE неверен в таблицах, где я делал objects.create (). То есть до импорта было 50, а после 50 еще 50, хотя в таблице теперь 150 объектов. Это, конечно, приводит к ошибкам при создании новых объектов, поскольку он пытается использовать идентификатор, который уже существует (во всех этих таблицах идентификатор - это просто поле автоинкремента ванили). Однако таблицы, которые были заполнены с помощью ./manage.py loaddata, выглядят хорошо.

Я знаю, что могу вручную сбросить эти таблицы с помощью Django ./manage.py sqlsequenreset, но мне любопытно, почему последовательность, кажется, выходит из строя в первую очередь. Разве objects.create () не увеличивает его? Я пропускаю что-то очевидное?

Ответы [ 2 ]

12 голосов
/ 19 января 2010

все отлично работает. create () django не имеет никакого отношения к непосредственному внедрению последовательности. Кратко:

  • postgresql автоинкремент («серийный» тип) это просто ярлык 'создать последовательность + создать целое число поле со значением последовательности по умолчанию '
  • первичный ключ автозаполя django (id целое число, если не указано иное вами) просто создает последовательное поле
  • при указании идентификатора вручную, Postgres вставляет значение в база данных. когда вы указываете значение, он пропускает параметр «по умолчанию», что является правильным поведением.

Итак, если вы хотите, чтобы ваши вставки увеличивали последовательность по вашему выбору, вам нужно вручную изменить значение последовательности, используя SELECT setval ('sequence_name', int_value); в противном случае оставьте его пустым, и он будет увеличиваться автоматически - выберите текущее значение val и увеличьте его на +1 (если не указано иначе в определении последовательности).

другая идея заключается в том, что вы создаете объект, а затем обновляете идентификатор (конечно, он уже не может быть использован) и, в конце концов, устанавливаете значение последовательности в максимальный идентификатор.

2 голосов
/ 18 января 2010

Поля автоинкремента работают, но вы должны сделать запрос как

MyObject.objects.create(title='foo')

без поля id, автоматически рассчитывается с базой данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...