﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
29497	Saving parent object after setting on child leads to unexpected data loss in bulk_create().	Robin Ramael	Hannes Ljungberg	"Example:

{{{#!python

class Country(models.Model):
    name = models.CharField(max_length=255)
    iso_two_letter = models.CharField(max_length=2)
    description = models.TextField()


class City(models.Model):
    name = models.CharField(max_length=255)
    country = models.ForeignKey(Country, on_delete=models.CASCADE)


class BulkCreateTests(TestCase):
    def test_fk_bug(self):
        country_nl = Country(name='Netherlands', iso_two_letter='NL')
        country_be = Country(name='Belgium', iso_two_letter='BE')

        city = City(country=country_be, name='Brussels')  # (1)
        country_be.save()  # (2)

        city.save()
}}}

This results in an integrity error:

{{{
======================================================================
ERROR: test_fk_bug (bulk_create.tests.BulkCreateTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ""/Users/robin/src/django/django/db/backends/utils.py"", line 85, in _execute
    return self.cursor.execute(sql, params)
psycopg2.IntegrityError: null value in column ""country_id"" violates not-null constraint
DETAIL:  Failing row contains (1, Brussels, null).


The above exception was the direct cause of the following exception:

...

----------------------------------------------------------------------
}}}

I wonder wether there's a reason that this doesn't work. If setting a related object on a model instance automatically sets instance.related_object_id, you'd expect this behavior to continue working if the related object receives its primary key after the referencing instance was initialized.

Of course, switching lines (1) and (2) makes it all work, but this behavior means that bulk creating with related objects (with postgres returning the primary keys, bless it's heart) becomes more complex than it should be, forcing the user to use mappings or even set the foreign keys themselves:

{{{#!python
for country_data, city_data in data:
    country = Country(**country_data)
    countries.append(country)
    city = City(country=country, **city_data)
    cities.append(city)

Country.objects.bulk_create(countries)

# needs this for the bulk create to not give an integrity error:
for city in cities:
    city.country_id = city.country.id

City.objects.bulk_create(cities)
}}}

Ideally, the main instance would, when saved, 'reach into' its related objects and set the foreign key field like the loop does. Is there a reason this can't work?"	Bug	closed	Database layer (models, ORM)	dev	Normal	fixed	orm, foreign key, bulk_create		Accepted	1	0	0	0	0	0
