#14896 closed (fixed)
Delete leads to IntegrityError : bad cascading rule when there's a ManyToManyField pointing to a class having subclasses.
Reported by: | tbrizzi | Owned by: | Carl Meyer |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.3-alpha |
Severity: | Keywords: | blocker | |
Cc: | Alexander Koshelev | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I'm working on a scientific Django based application. One of its features is to store all researchers of a laboratory and relative contacts like addresses, phones, faxes, websites or emails :
class Contact(Cast): """Base class of all type of contacts like Address, Phone, Fax, E-mail or Website.""" label = models.CharField(max_length=100) def __unicode__(self): return self.label class Meta : ordering = ['label'] class EMail(Contact): """A subclass of Contact to store an EMail address.""" identifier = models.EmailField(verbose_name="address", max_length=256) def __unicode__(self): st = "%s : %s" % (self.label, self.identifier) return st class Meta: verbose_name = "e-mail" class Researcher(models.Model): """Anybody working in a ScientificStructure.""" first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) photo = models.ImageField(upload_to="uploads/images/photos", null=True, blank=True) db_user = models.OneToOneField(User, null=True, blank=True, verbose_name="database user") contacts = models.ManyToManyField(Contact, null=True, blank=True) notes = models.TextField(null=True, blank=True) def get_full_name(self): """Get the full name of a Researcher, i.e. the combination between its first and last names.""" return "%s %s" % (self.first_name, self.last_name) def __unicode__(self): return self.get_full_name() class Meta: ordering = ['last_name', 'first_name']
From IPython, I create and link together a Researcher and an EMail address :
In [1]: from helmholtz.people.models import EMail, Researcher In [2]: researcher = Researcher.objects.create(first_name='Django', last_name='Reinhardt') In [3]: email = EMail.objects.create(label='django reinhardt email', identifier='django.reinhardt@gmail.com') In [4]: researcher.contacts.add(email)
When I execute the following piece of code from IPython, the interpreter returns this :
In [5]: email.delete() --------------------------------------------------------------------------- IntegrityError Traceback (most recent call last) C:\Users\Thierry.NeuroInf-DB_2\<ipython console> in <module>() D:\Thierry\Projects\django-svn\django\db\models\base.pyc in delete(self, using) 577 collector = Collector(using=using) 578 collector.collect([self]) --> 579 collector.delete() 580 581 delete.alters_data = True D:\Thierry\Projects\django-svn\django\db\models\deletion.pyc in decorated(self, *args, **kwargs) 48 func(self, *args, **kwargs) 49 if forced_managed: ---> 50 transaction.commit(using=self.using) 51 else: 52 transaction.commit_unless_managed(using=self.using) D:\Thierry\Projects\django-svn\django\db\transaction.pyc in commit(using) 199 using = DEFAULT_DB_ALIAS 200 connection = connections[using] --> 201 connection._commit() 202 set_clean(using=using) 203 D:\Thierry\Projects\django-svn\django\db\backends\postgresql_psycopg2\base.pyc in _commit(self) 198 if self.connection is not None: 199 try: --> 200 return self.connection.commit() 201 except Database.IntegrityError, e: 202 raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2] IntegrityError: ERROR: UPDATE or DELETE on table "people_contact" violates foreign key constraint "people_researcher_contacts_contact_id_fkey" on table "people_researcher_contacts" DETAIL: key (id)=(5) is still referenced from table "people_researcher_contacts".
Seems there's a bad cascading rule when there's a many to many field pointing to a class having subclasses.
This error has never happened before Django 1.3 alpha.
Attachments (2)
Change History (11)
by , 14 years ago
Attachment: | django-14896.diff added |
---|
comment:1 by , 14 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
I concur with Alex. I can't reproduce this using the details you provide, and I can't see an obvious set of circumstances that would cause this bug to occur.
However, it's a very concerning -- the cascading rules have changed in 1.3, so we want to make this really isn't a bug. Confirming this is a high priority issue for 1.3 final. I'm closing worksforme right now, but please reopen it if you can provide any more details.
Ideally, this would come in the form of a modification to Alex's attached test case that fails.
comment:2 by , 14 years ago
Resolution: | worksforme |
---|---|
Status: | closed → reopened |
Error occurs during commit, therefore test method needs to be in a TransactionTestCase in order to see the problem:
--> ./runtests.py --settings=testdb.postgres -v1 delete_regress Creating test database for alias 'default'... Creating test database for alias 'other'... Destroying old test database 'other'... ...E. ====================================================================== ERROR: test_inheritance (regressiontests.delete_regress.tests.DeleteCascadeTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/kmtracey/django/trunk/tests/regressiontests/delete_regress/tests.py", line 119, in test_inheritance email.delete() File "/home/kmtracey/django/trunk/django/db/models/base.py", line 579, in delete collector.delete() File "/home/kmtracey/django/trunk/django/db/models/deletion.py", line 50, in decorated transaction.commit(using=self.using) File "/home/kmtracey/django/trunk/django/db/transaction.py", line 201, in commit connection._commit() File "/home/kmtracey/django/trunk/django/db/backends/postgresql_psycopg2/base.py", line 200, in _commit return self.connection.commit() IntegrityError: update or delete on table "delete_regress_contact" violates foreign key constraint "delete_regress_researcher_contacts_contact_id_fkey" on table "delete_regress_researcher_contacts" DETAIL: Key (id)=(1) is still referenced from table "delete_regress_researcher_contacts". ---------------------------------------------------------------------- Ran 5 tests in 2.766s FAILED (errors=1) Destroying test database for alias 'default'... Destroying test database for alias 'other'...
by , 14 years ago
Attachment: | 14896-test.diff added |
---|
Test that demonstrates the problem, fails on trunk, passes on 1.2.X
comment:3 by , 14 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:5 by , 14 years ago
Keywords: | blocker added |
---|
comment:6 by , 14 years ago
Cc: | added |
---|
comment:7 by , 14 years ago
Owner: | changed from | to
---|---|
Status: | reopened → new |
comment:8 by , 14 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Fixed in [15248]. Thanks to tbrizzi for the report, and Karen, Alex, Russ, and Ramiro for confirmation and test case.
I can't reproduce this issue.