Я перевожу сайт Django с MySQL на PostgreSQL. Количество данных невелико, поэтому я выбрал очень простой подход: я просто использовал встроенные подпрограммы Django serialize и десериализованно для создания записей JSON, а затем загружал их в новый экземпляр, переберите объекты и сохраните каждый из них в новой базе данных.
Это работает очень хорошо, с одним отклонением: после загрузки всех записей я сталкиваюсь с IntegrityError
, когда пытаюсь добавить новые данные после загрузки старых записей. Postgres-эквивалент поля идентификатора автоинкремента MySQL является последовательным полем, но внутренний счетчик для последовательных полей не увеличивается, если значения идентификатора указаны явно. В результате Postgres пытается начать нумерацию записей с 1 - уже используется - что вызывает нарушение ограничения. (Это известная проблема в Django, помеченная wontfix .)
Есть довольно много вопросов и ответов, связанных с этим, но, похоже, ни один из ответов не касается проблемы непосредственно в контексте Django. В этом ответе приведен пример запроса, который необходимо выполнить для обновления счетчика, но я стараюсь по возможности избегать явных запросов. Я мог бы просто удалить поле ID перед сохранением и позволить Postgres самому выполнить нумерацию, но в этом случае есть ссылки ForeignKey
, которые будут нарушены. А все остальное работает прекрасно!
Было бы неплохо, если бы Джанго предоставил для этого рутину, которая разумно обрабатывает любые крайние случаи. (Это не исправит ошибку, но позволит разработчикам работать с ней последовательно и корректно.) Нужно ли нам просто использовать необработанный запрос, чтобы это исправить? Это кажется таким варварским.
Если на самом деле такой подпрограммы не существует, я просто сделаю что-то вроде нижеприведенного, что напрямую запускает запрос, предложенный в ответе, связанном выше. (Или я верю - это не проверено. Я отредактирую это после тестирования.) Но в этом случае мне было бы интересно услышать о любых потенциальных проблемах с этим подходом или любой другой информации о том, что я могу делать неправильно , Например, я должен просто изменить записи, чтобы использовать вместо них UUID, так как предполагает ?
Вот грубый подход.
SomeTable.objects.raw(
"SELECT setval('your_sequence_name', (SELECT max(id) FROM some_table));"
)