#10454 closed (duplicate)
IntegrityError while deleting object with complex constraint
| Reported by: | liangent | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Keywords: | ||
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
i have models like this (the whole project is too complex and i dont want to put it here):
class P(Model):
pass
class TC(Model):
p = ForeignKey(P)
class S(Model):
p = ForeignKey(P)
class CR(Model):
s = ForeignKey(S)
tc = ForeignKey(TC) # note: s.p always equals to tc.p
when i'm trying to delect a P object (with all its TC, S, CR sub-objects existing), an IntegrityError occurs, saying Cannot delete or update a parent row: a foreign key constraint fails (`proj/m_tc`, CONSTRAINT `p_id_refs_id_16cb2ff4a6a127c1` FOREIGN KEY (`p_id`) REFERENCES `main_p` (`id`))') .
Environment:
Request Method: POST
Request URL: http://example.com/admin/m/p/2/delete/
Django Version: 1.1 pre-alpha
Python Version: 2.5.2
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.redirects',
'django.contrib.comments',
'django.contrib.flatpages',
'notification',
'avatar',
'tagging',
'announcements',
'registration',
'proj.cm',
'proj.m',
'proj.u',
'proj.mk']
Installed Middleware:
('django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.redirects.middleware.RedirectFallbackMiddleware',
'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
'django.contrib.csrf.middleware.CsrfMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.transaction.TransactionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'proj.middleware.CAM',
'django.middleware.doc.XViewMiddleware')
Traceback:
File "/usr/lib/python2.5/site-packages/django/core/handlers/base.py" in get_response
86. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python2.5/site-packages/django/contrib/admin/sites.py" in root
450. return self.model_page(request, *url.split('/', 2))
File "/usr/lib/python2.5/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
44. response = view_func(request, *args, **kwargs)
File "/usr/lib/python2.5/site-packages/django/contrib/admin/sites.py" in model_page
469. return admin_obj(request, rest_of_url)
File "/usr/lib/python2.5/site-packages/django/contrib/admin/options.py" in __call__
799. return self.delete_view(request, unquote(url[:-7]))
File "/usr/lib/python2.5/site-packages/django/contrib/admin/options.py" in delete_view
722. obj.delete()
File "/usr/lib/python2.5/site-packages/django/db/models/base.py" in delete
464. delete_objects(seen_objs)
File "/usr/lib/python2.5/site-packages/django/db/models/query.py" in delete_objects
1014. del_query.delete_batch(pk_list)
File "/usr/lib/python2.5/site-packages/django/db/models/sql/subqueries.py" in delete_batch
88. self.do_query(self.model._meta.db_table, where)
File "/usr/lib/python2.5/site-packages/django/db/models/sql/subqueries.py" in do_query
35. self.execute_sql(None)
File "/usr/lib/python2.5/site-packages/django/db/models/sql/query.py" in execute_sql
1996. cursor.execute(sql, params)
File "/usr/lib/python2.5/site-packages/django/db/backends/util.py" in execute
19. return self.cursor.execute(sql, params)
File "/usr/lib/python2.5/site-packages/django/db/backends/mysql/base.py" in execute
83. return self.cursor.execute(query, args)
File "/var/lib/python-support/python2.5/MySQLdb/cursors.py" in execute
166. self.errorhandler(self, exc, value)
File "/var/lib/python-support/python2.5/MySQLdb/connections.py" in defaulterrorhandler
35. raise errorclass, errorvalue
Exception Type: IntegrityError at /admin/m/p/2/delete/
Exception Value: (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`proj/m_tc`, CONSTRAINT `p_id_refs_id_16cb2ff4a6a127c1` FOREIGN KEY (`p_id`) REFERENCES `m_p` (`id`))')
Change History (9)
comment:1 by , 17 years ago
follow-up: 3 comment:2 by , 17 years ago
I ran the same test with MySQL/InnoDB and trunk, and I also did not get the error. It seems likely there is some other complication that is not apparent in the ticket. For example, does this only happen when deleting from a particular view?
comment:3 by , 17 years ago
Replying to ikelly:
I ran the same test with MySQL/InnoDB and trunk, and I also did not get the error. It seems likely there is some other complication that is not apparent in the ticket. For example, does this only happen when deleting from a particular view?
i only tried to delete it from django's admin site.
comment:4 by , 17 years ago
I can't reproduce this through the admin site either. The only way this is going to progress is if you can produce a test case for this that exhibits the bug outside your large project.
comment:5 by , 17 years ago
did you add 'django.middleware.transaction.TransactionMiddleware',?
the bug disappeared after i removed TransactionMiddleware from middleware list.
comment:6 by , 17 years ago
i tried to read django source code, and found this:
def add(self, model, pk, obj, parent_model, nullable=False):
"""
Adds an item to the container.
Arguments:
* model - the class of the object being added.
* pk - the primary key.
* obj - the object itself.
* parent_model - the model of the parent object that this object was
reached through.
* nullable - should be True if this relation is nullable.
Returns True if the item already existed in the structure and
False otherwise.
"""
d = self.data.setdefault(model, SortedDict())
retval = pk in d
d[pk] = obj
# Nullable relationships can be ignored -- they are nulled out before
# deleting, and therefore do not affect the order in which objects
# have to be deleted.
if parent_model is not None and not nullable:
self.children.setdefault(parent_model, []).append(model)
return retval
yes, there's some nullable foreignkeys pointing to P model/object in another model (i forgot to mention it above), and code below
for field, model in cls._meta.get_fields_with_model():
if (field.rel and field.null and field.rel.to in seen_objs and
filter(lambda f: f.column == field.column,
field.rel.to._meta.fields)):
assert False # i added an assert here
if model:
sql.UpdateQuery(model, connection).clear_related(field,
pk_list)
else:
update_query.clear_related(field, pk_list)
i didn't catch any assertion error...
comment:7 by , 17 years ago
in filter(lambda f: f.column == field.column, field.rel.to._meta.fields)
i cannot understand why, if model A:field F is pointing to model B, we can get the result that if F has the same column name as a field in model B then clear field F..
comment:8 by , 17 years ago
the bug also disappears after removing and filter(lambda f: f.column == field.column, field.rel.to._meta.fields), but i'm not sure if there's other side-effect.
comment:9 by , 17 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | new → closed |
Sounds like this is the same issue as #9308. That ticket has a patch that is supposed to resolve it.
Using your models, the following example runs OK with postgresql_psycopg2 and sqlite3.