Загрузка приспособления Django, содержащего натуральные ключи - PullRequest
3 голосов
/ 01 марта 2012

Как загрузить приспособление Django, чтобы модели, на которые ссылаются естественные ключи, не конфликтовали с уже существующими записями?

Я пытаюсь загрузить такое приспособление, но получаю IntegrityErrors отмой сервер MySQL, жалующийся на то, что Django пытается вставить дублирующиеся записи, что не имеет никакого смысла.

Как я понимаю, естественная ключевая функция Django, чтобы полностью поддерживать использование dumpdata и loaddata, вам нужно определитьnatural_key метод в модели и get_by_natural_key метод в менеджере модели.

Так, например, у меня есть две модели:

class PersonManager(models.Manager):
    def get_by_natural_key(self, name):
        return self.get(name=name)

class Person(models.Model):

    objects = PersonManager()

    name = models.CharField(max_length=255, unique=True)

    def natural_key(self):
        return (self.name,)

class BookManager(models.Manager):
    def get_by_natural_key(self, title, *person_key):
        person = Person.objects.get_by_natural_key(*person_key)
        return self.get(title=title, person=person)

class Book(models.Model):

    objects = BookManager()

    author = models.ForeignKey(Person)

    title = models.CharField(max_length=255)

    def natural_key(self):
        return (self.title,) + self.author.natural_key()
    natural_key.dependencies = ['myapp.Person']

Моя тестовая база данных уже содержитПример записи о человеке и книге, которую я использовал для создания прибора:

[
    {
        "pk": null, 
        "model": "myapp.person", 
        "fields": {
            "name": "bob"
        }
    }, 
    {
        "pk": null, 
        "model": "myapp.book", 
        "fields": {
            "author": [
                "bob"
            ], 
            "title": "bob's book", 
        }
    }
]

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

Однако, когда я запускаю python manage.py loaddata myfixture.json, я получаю сообщение об ошибке:

IntegrityError: (1062, "Duplicate entry '1-1' for key 'myapp_person_name_uniq'")

Почему Django пытается воссоздатьзапись Person вместо повторного использования уже существующей?

Ответы [ 2 ]

1 голос
/ 30 марта 2015

Оказывается, решение требует очень незначительного исправления для команды loaddata Джанго. Поскольку маловероятно, что разработчики Django примут такой патч, я разветвил его в своем пакете различных улучшений, связанных с администратором Django.

Смена кода ключа (строки 189-201 loaddatanaturally.py) просто включает в себя вызов get_natural_key(), чтобы найти любой существующий pk внутри цикла, который перебирает десериализованные объекты.

0 голосов
/ 10 июня 2012

На самом деле loaddata не должен работать с существующими данными в базе данных, он обычно используется для начальной загрузки моделей.Посмотрите на этот вопрос для другого способа сделать это: Импорт данных в модель Django с существующими данными?

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