Проблемы с типами содержимого при загрузке прибора в Django - PullRequest
99 голосов
/ 12 мая 2009

У меня проблемы с загрузкой приборов Django в базу данных MySQL из-за конфликтов типов содержимого. Сначала я попытался сбросить данные только из моего приложения следующим образом:

./manage.py dumpdata escola > fixture.json

но у меня постоянно возникали проблемы с внешним ключом, потому что мое приложение "escola" использует таблицы из других приложений. Я продолжал добавлять дополнительные приложения, пока не дошел до этого:

./manage.py dumpdata contenttypes auth escola > fixture.json

Теперь проблема заключается в следующем нарушении ограничения при попытке загрузить данные в качестве тестового устройства:

IntegrityError: (1062, "Duplicate entry 'escola-t23aluno' for key 2")

Кажется, проблема в том, что Django пытается динамически воссоздать типы контента с различными значениями первичного ключа, которые конфликтуют со значениями первичного ключа из устройства. Это похоже на ошибку, описанную здесь: http://code.djangoproject.com/ticket/7052

Проблема в том, что рекомендуемый обходной путь - сбросить приложение contenttypes, которое я уже делаю !? Что дает? Если это имеет какое-то значение, у меня есть некоторые пользовательские разрешения модели, как описано здесь: http://docs.djangoproject.com/en/dev/ref/models/options/#permissions

Ответы [ 12 ]

136 голосов
/ 02 ноября 2010

manage.py dumpdata --natural будет использовать более надежное представление внешних ключей. В джанго они называются «естественными ключами». Например:

  • Permission.codename используется в пользу Permission.id
  • User.username используется в пользу User.id

Подробнее: секция естественных ключей в "сериализации объектов django"

Некоторые другие полезные аргументы для dumpdata:

  • --indent=4 сделать его читабельным для человека.
  • -e sessions исключить данные сеанса
  • -e admin исключить историю действий администратора на сайте администратора
  • -e contenttypes -e auth.Permission исключать объекты, которые воссоздаются автоматически из схемы каждый раз во время syncdb. Используйте его только вместе с --natural, иначе вы можете получить плохо выровненные идентификаторы.
33 голосов
/ 13 мая 2009

Да, это действительно раздражает. Некоторое время я работал над этим, выполняя «manage.py reset» в приложении contenttypes перед загрузкой фикстуры (чтобы избавиться от автоматически сгенерированных данных contenttypes, которые отличались от сброшенной версии). Это сработало, но в конце концов мне надоели неприятности и отказались от приспособлений, полностью отдавая предпочтение прямым дампам SQL (конечно, тогда вы теряете переносимость БД).

update - лучший ответ - использовать флаг --natural для dumpdata, как указано в ответе ниже. Этот флаг еще не существовал, когда я писал этот ответ.

30 голосов
/ 30 мая 2010

Попробуйте пропустить типы содержимого при создании прибора:

./manage.py dumpdata --exclude contenttypes > fixture.json

У меня сработало в аналогичной ситуации для юнит-тестов, ваше понимание действительно помогло!

25 голосов
/ 05 мая 2017

Ответы здесь все старые ... По состоянию на 2017 год лучший ответ:

manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4
11 голосов
/ 12 ноября 2016

Я не использовал MySQL, а импортировал некоторые данные с живого сервера в sqlite. Очистка данных приложения contenttypes перед выполнением loaddata сделала свое дело:

from django.contrib.contenttypes.models import ContentType
ContentType.objects.all().delete()
quit()

А потом

python manage.py loaddata data.json
10 голосов
/ 04 октября 2010

Я решил эту проблему в своих тестовых примерах, сбросив приложение contenttypes из модульного теста перед загрузкой файла дампа. Карл предложил это, используя команду manage.py, и я делаю то же самое, только используя метод call_command:

>>> from django.core import management
>>> management.call_command("flush", verbosity=0, interactive=False)
>>> management.call_command("reset", "contenttypes", verbosity=0, interactive=False)
>>> management.call_command("loaddata", "full_test_data.json", verbosity=0)

My full_test_data.json содержит дамп приложения contenttypes, который соответствует остальным тестовым данным. Сбрасывая приложение перед загрузкой, оно предотвращает дублирование ключа IntegrityError.

6 голосов
/ 21 июня 2017
python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth.Permission --exclude=admin.logentry --exclude=sessions.session --indent 4 > initial_data.json

Это работает для меня. Здесь я исключаю все, кроме реальных моделей.

  • Если вы видите любую другую модель, кроме созданных вами моделей, вы можете смело исключать их. Одним из недостатков этого подхода является потеря данных журнала, а также данных аутентификации.
3 голосов
/ 07 декабря 2018

Вам необходимо использовать естественные ключи для представления любого внешнего ключа и отношений «многие ко многим». Более того, было бы неплохо исключить таблицу session в приложении sessions и таблицу logentry в приложении admin.

Джанго 1,7 +

python manage.py dumpdata --natural-foreign --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json

Джанго <1,7 </strong>

python manage.py dumpdata --natural --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json

Согласно документации Django , --natural устарел в версии 1.7, поэтому вместо него следует использовать опцию --natural-foreign.

Вы также можете опустить первичный ключ в сериализованных данных этого объекта, так как он может быть вычислен во время десериализации путем передачи флага --natural-primary.

python manage.py dumpdata --natural-foreign --natural-primary --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json
1 голос
/ 25 января 2018
./manage.py dumpdata app.Model --natural-foreign

изменится

  "content_type": 123

до

  "content_type": [
    "app_label",
    "model"
  ],

И прибор работает на TestCase сейчас

1 голос
/ 05 июля 2016

Я встречал подобную ошибку иногда назад. Оказалось, что я пытался загрузить приборы перед созданием необходимых таблиц. Итак, я сделал:

$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py loaddata fixtures/initial_data.json

И это сработало как шарм

...