it-swarm.com.ru

Проблемы с типами содержимого при загрузке устройства в Django

У меня проблемы с загрузкой 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

97
user27478

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, иначе вы можете получить плохо выровненные идентификаторы.
131
Ski

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

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

33
Carl Meyer

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

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

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

30
Evgeny

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

manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4
24
SmallChess

Я решил эту проблему в своих тестовых случаях, сбросив приложение 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)

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

10
Jesse L

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

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

А потом

python manage.py loaddata data.json
9
MadeOfAir
python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth.Permission --exclude=admin.logentry --exclude=sessions.session --indent 4 > initial_data.json

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

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

Я собираюсь дать еще один возможный ответ, который я только что понял. Может быть, это поможет ОП, может быть, это поможет кому-то еще.

У меня есть таблица отношений «многие ко многим». Он имеет первичный ключ и два внешних ключа для других таблиц. Я обнаружил, что если у меня есть запись в приборе, чьи два внешних ключа совпадают с другой записью, уже имеющейся в таблице с разными pk, это не удастся. Таблицы отношений M2M имеют «уникальное вместе» для двух внешних ключей.

Так что, если нарушаются отношения M2M, посмотрите на добавляемые внешние ключи, посмотрите на свою базу данных, чтобы увидеть, есть ли эта пара FK в списке под другим PK.

1
orblivion
./manage.py dumpdata app.Model --natural-foreign

изменится 

  "content_type": 123

в

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

И сейчас крепеж работает для TestCase

1
Daniil Mashkin

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

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

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

1
James Wanderi

Это действительно очень раздражает ... Меня это укушает каждый раз.

Я пытался сбросить данные с --exclude contenttypes и --natural, у меня всегда возникают проблемы ..

Что лучше всего работает для меня, так это просто делать truncate table Django_content_type; после syncdb и затем загружать данные.

Конечно, для автозагрузки initial_data.json вам нужен шарик.

1
h3.

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

Django 1.7+

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

Django <1,7

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
0
lmiguelvargasf