Code

Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#13834 closed (invalid)

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

Reported by: claudep 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: UI/UX:

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 claudep 4 years ago.
Add an assertion about natural_key method return value type

Download all attachments as: .zip

Change History (3)

comment:1 Changed 4 years ago by ramiro

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

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 Changed 4 years ago by claudep

Argh... My bad!

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

Changed 4 years ago by claudep

Add an assertion about natural_key method return value type

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.