I'm using django 1.6, and I have 2 models referencing each other like so:
class Person(models.Model):
address = models.ForeignKey('Address', blank=False)
class Address(models.Model):
person = models.ForeignKey(Person, blank=False)
The reason I have cyclic foreign key's is for data integrity. Because an address may be assigned to exactly one user, and a user must have at least one address. And yes, I know I can live without this, but I would rather not.
I'm using PostgreSQL with my foreign keys DEFERRABLE INITIALLY DEFERRED
, and I want to use transactions to insert the data into those tables.
However, when I try to use transaction.atomic():
, it does not behave as expected within my view.
Here is what I am doing:
with transaction.atomic():
addr = Address(street='125 fake street')
addr.save()
person = Person()
person.address_id = addr.id
addr.person_id = person.id
addr.save()
person.save()
However, I keep getting an IntegrityError
the first time I call addr.save()
Any suggestions what I'm doing wrong? Is there a better way to to that?
The problem here is, because PostgreSQL does not wait untill the end of transaction to check for NOT NULL.
"NOT NULL and CHECK constraints are always checked immediately when a row is inserted or modified (not at the end of the statement)."
And my columns were set to NOT NULL.
As a workaround, I'm doing this
with transaction.atomic():
addr = Address()
addr.person_id = 0 # setting this temporarily to Zero
addr.save()
person = Person()
person.address_id = addr.id
person.save()
addr.person_id = person.id
addr.save()
This allows me to insert into the database, and update the foreign keys later, and still fail with if no foreign key matches, because I will never have a value of Zero for id value.