Search code examples
pythondjangopostgresqldjango-modelsmany-to-many

Efficiently bulk updating many ManyToMany fields


A version of this question has been asked here several times but none of the answers provided solve my exact problem.

I'm trying to bulk_create a batch of objects of a model with a ManyToMany field.

In this case, the ManyToMany field refers to the same model, though I'd also be interested in the general case.

Let's say this is my model:

class Person(models.Model):
    name = models.CharField(max_length=20, blank=True, null=True)
    friends = models.ManyToMany("self", related_name="friends_with", null=True)

After bulk_creating a large number of Person objects, I want to add the information who's friends with whom within this group.

Is there a more efficient way to go about this than looping through each new Person and calling .set(friend_pks) or .add(*friend_pks)?

I.e., an analogue of bulk_update. I've achieved some speed-up by wrapping the loop into with transaction.atomic() (from this answer) but it's still quite slow.


Solution

  • Okay, my post was premature -- it seems that this answers the question.

    The key is to bulk_create the through models. In this example:

    friends_relation_1 = Person.friends.through(from_person_id=1, to_person_id=2)
    friends_relation_2 = Person.friends.through(from_person_id=2, to_person_id=8)
    
    Person.friends.through.objects.bulk_create([friends_relation_1, friends_relation_2, ...])