Code

Opened 2 years ago

Closed 3 months ago

Last modified 3 months ago

#18285 closed Cleanup/optimization (fixed)

bulk_create and ManyToMany relationships: the relationship is actually not made

Reported by: Michael PALUMBO <michael.palumbo87@…> Owned by: nobody
Component: Documentation Version: 1.4
Severity: Normal Keywords: bulk_create, relationship
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

bulk_create with relationships does not work: i.e. the relationship is not made.

For example:

class Company(models.Model):
    url = models.URLField(unique=True)

class Website(models.Model):
    url = models.URLField(unique=True) 
    companies = models.ManyToManyField(Company, null=True, blank=True)

list_companies = [Company(url='...'), Company(url='...')]
w.companies.bulk_create(list_companies)
-> [< Company:  Company object>, < Company:  Company object>]   #The 2 Company objects are created

w.companies.all()
-> []   # But the relationship is broken

The 2 companies are created but I cannot access to them through the many-to-many relationship.
I looked at the database and yes I can find the 2 companies in the company table but no rows in the website_company table.

Discussed on django developers group: https://groups.google.com/forum/?fromgroups#!topic/django-developers/VNhDD2Golws

Attachments (0)

Change History (4)

comment:1 Changed 2 years ago by akaariai

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

I quickly checked the related fields for .create() support and both reverse foreign key and m2m field has support for create.

I think my current approach would be to add bulk_create() support for reverse foreign key (as it is somewhat easy to do so), and just raise NotImplemented from m2m.bulk_create(). Fixing the m2m bulk_create would require support for returning the primary key value from bulk_insert to create the links, and that support is not currently available (and is not going to be available in the foreseeable future).

In addition generic relations need a check for this, too.

Version 0, edited 2 years ago by akaariai (next)

comment:2 Changed 22 months ago by moritzs

  • Component changed from Database layer (models, ORM) to Documentation
  • Type changed from Bug to Cleanup/optimization

Documentation says:

This has a number of caveats though:

  • The model's save() method will not be called, and the pre_save and post_save signals will not be sent.
  • It does not work with child models in a multi-table inheritance scenario.
  • If the model's primary key is an AutoField it does not retrieve and set the primary key attribute, as save() does.

There is a reason why the bulk_create method does not call the models' save methods. It should be a fast alternative to call the models' save methods in a loop.

So I think the documentation should be clarified rather then modifying bulk_create.

Last edited 22 months ago by moritzs (previous) (diff)

comment:3 Changed 3 months ago by Tim Graham <timograham@…>

  • Resolution set to fixed
  • Status changed from new to closed

In 9173d2cb746f253ca31183eb63ac47e440c74ce3:

Fixed #18285 -- Documented that bulk_create doesn't work with M2M relationships.

comment:4 Changed 3 months ago by Tim Graham <timograham@…>

In b1cc1633e0ae2b74611dde2b832c0368c2984b4e:

[1.6.x] Fixed #18285 -- Documented that bulk_create doesn't work with M2M relationships.

Backport of 9173d2cb74 from master

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.