OOPS, turns out I had a post_save receiver creating the reciprocal rel. So 
this is not a django problem.

On Wednesday, August 29, 2012 1:40:52 PM UTC-7, Hobson Lane wrote:
>
> In django 1.4, my model save() gets called for ManyToManyField "through" 
> models for loaddata on that model:
>
>     class Entity(models.Model):
>         related_entities = models.ManyToManyField('self', 
> through='EntityRelationship', symmetrical=False, related_name='related_to+')
>     
>     class EntityRelationship(models.Model):
>         from_entity       = models.ForeignKey(Entity, 
> related_name='from_entities')
>         to_entity           = models.ForeignKey(Entity, 
> related_name='to_entities')
>
>         def save(self, *args, **kwargs):
>             print >>sys.stderr, EntityRelationship.objects.all()
>             super(EntityRelationship, self).save(*args, **kwargs) 
>             print >>sys.stderr, EntityRelationship.objects.all()
>             assert False
>
>         class Meta:
>             db_table     = u'EntityRelationship'
>             ordering = ["to_entity"]
>             unique_together = (('from_entity','to_entity'))
>
>         def __unicode__(self):
>             return '%s -> %s'%(self.from_entity.pk,self.to_entity.pk)
>            
> Interestingly, `save()` is not called for the forward relationship, the 
> one explicity specified in the json fixture. loaddata must do a "raw" 
> insert for this one. But is called as part of validation of the 
> relationship when inserting a record for the reciprocal relationship:
>
>     >>> manage.py loaddata fixtures/EntityRelationship.json
>     [<EntityRelationship: 1 -> 2>]
>     [<EntityRelationship: 1 -> 2>, <EntityRelationship: 2 -> 1>]
>
> I wouldn't expect loaddata should insert a receiprocal relationship record 
> not specified in the fixture. And doing so without calling save() for both 
> inserts makes it very difficult to deal with fixtures that contain a random 
> network of connected entities. You eventually get an IntegrityError during 
> the loaddata because duplicate records (relationships) have already been 
> entered. And it prevents the user from loading a fixture of asymmetrical 
> (not necessarily a reciprocal relationship for every edge of the graph) 
> relationships. At least I'm having trouble doing so.
>
> Perhaps the '+' in the related name ('related_to+') is causing me grief, 
> or some other subtlety of self-referential relationships in Django that I 
> don't understand.
>
> On Tuesday, March 29, 2011 11:21:43 PM UTC-7, George Karpenkov wrote:
>>
>> If we'll look into core/management/commands/loaddata we'll see the 
>> line 
>> "obj.save(using=using)" which saves the data. 
>>
>> *however* consider the case when application has some custom database- 
>> altering logic in .save method. The common thing that comes to mind is 
>> timestamp, or something similar. What would happen is that instead of 
>> loading data the data from the fixture will be partly changed, which 
>> is really not what you want. 
>>
>> That's not the worst case though - I've just spent 40 minutes loading 
>> the database from a fixture which contained data in django-tagging, 
>> which inserts it's own "INSERT" SQL statements into save. So loaddata 
>> was consistently crashing with "column blah is not unique" while the 
>> data from the dump was perfectly fine. It made me quite sad. 
>>
>> so coming to think of it i can't really think of a use case where 
>> you'd want the custom logic in .save() to be executed. All the data is 
>> already there, and we *know* that it is valid data - so what else we 
>> might possibly want to do with it? (unless our application 
>> communicates over network with different services and it uses .save() 
>> to maintain integrity with them, but I haven't seen a single django 
>> website like that) 
>> So I think that some lower-level logic should be called instead. 
>>
>> Any comments on why loaddata was implemented this way in the first 
>> place?
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/UM2eZoJRMP0J.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to