Opened 14 years ago

Closed 14 years ago

Last modified 14 years ago

#13834 closed (invalid)

Dumpdata/loaddata cycle fails when using a single-field natural key

Reported by: Claude Paroz Owned by: nobody
Component: Core (Serialization) Version: 1.2
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Here is a sample model:

from django.db import models

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

class Ontology(models.Model):
    name        = models.CharField(max_length=32, unique=True)

    objects = OntologyManager()

    def natural_key(self):
        return self.name

class Term(models.Model):
    name        = models.CharField(max_length=255)
    ontology    = models.ForeignKey(Ontology)

Then create an ontology and a term linked to this ontology. Then run:

python manage.py dumpdata --natural --indent=1 > testdata.json
python manage.py loaddata testdata.json

And the result:

Problem installing fixture 'testdata.json': Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/commands/loaddata.py", line 165, in handle
    for obj in objects:
  File "/usr/local/lib/python2.6/dist-packages/django/core/serializers/json.py", line 38, in Deserializer
    for obj in PythonDeserializer(simplejson.load(stream), **options):
  File "/usr/local/lib/python2.6/dist-packages/django/core/serializers/python.py", line 119, in Deserializer
    value = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/fields/__init__.py", line 468, in to_python
    raise exceptions.ValidationError(self.error_messages['invalid'])
ValidationError: [u'This value must be an integer.']

The bug is probably around the if hasattr(field_value, '__iter__'): line in django/core/serializers/python.py (Deserializer function). If I manually add brackets around the Ontology name in the JSON file, the loaddata command succeeds.

Attachments (1)

natural_key_assertion.diff (677 bytes ) - added by Claude Paroz 14 years ago.
Add an assertion about natural_key method return value type

Download all attachments as: .zip

Change History (3)

comment:1 by Ramiro Morales, 14 years ago

Resolution: invalid
Status: newclosed

Your natural_key() model method should always return a tuple, no special treatment is given to a natural key with one element:

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

Reproduced the problem here with an your example code, then made that change and serializing/deserializing again worked flawlessly. From http://docs.djangoproject.com/en/dev/topics/serialization/#serialization-of-natural-keys: That method should always return a natural key tuple -- in this example, (first name, last name)

Closing this ticket.

comment:2 by Claude Paroz, 14 years ago

Argh... My bad!

But what about adding an assertion? This would help to catch the error sooner in the process.

by Claude Paroz, 14 years ago

Attachment: natural_key_assertion.diff added

Add an assertion about natural_key method return value type

Note: See TracTickets for help on using tickets.
Back to Top