IntegrityError: FOREIGN KEY constraint failed: Django 2.0.3

3,817 views
Skip to first unread message

Anon Ymous

unread,
Mar 21, 2018, 10:50:25 AM3/21/18
to Django users
Hi,

I am learning python by trying to create a small Django app.  I may have found a bug related to Django and/or sqlite3.  If you are stackoverflow folks then my initial post is there:  https://stackoverflow.com/questions/49361834/integrityerror-exception-in-deleteview-cbv

My app really is just creating a small web site to add users and figure out how to do CRUD operations in building user profiles.  I am using the following setup:

Django Version: 2.0.3
Python Version: 3.6.3
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_extensions',
'django.contrib.sites',
'allauth',
'allauth.account',
'allauth.socialaccount',
'auditlog',
'widget_tweaks',
'Members.apps.MembersConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'auditlog.middleware.AuditlogMiddleware']

I am using sqlite3 as the DB backend..

I can create the virgin project, tweak the settings file and do the initial "makemigrations" and "migrate".  This, of course, creates the Django "user" table(s).  I went about creating my own "profile" model that "extends" the User model by creating a "oneToOne" field that points back to User and specifies an "on_delete=models.CASCADE" clause:

class Profile(models.Model):
...
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
blank=False,
null=False,
)
...

The thing is the table that is created is given the constraint:

FOREIGN KEY(`user_id`) REFERENCES `auth_user`(`id`) DEFERRABLE INITIALLY DEFERRED,

but the "on delete cascade" clause is missing.  

I first noticed this when testing a profile delete operation.  I get a foreign key constraint violation.  Looking into that led me here to you guys.

I have added that clause to the table:

FOREIGN KEY(`user_id`) REFERENCES `auth_user`(`id`) on delete cascade DEFERRABLE INITIALLY DEFERRED,

but I still get the constraint violation.  I did more digging last night and see that at least one of the Django generated "user_*" tables also has a foreign key relationship back to the "user" table and that is also missing the cascade clause.

My guesses at this instant include:
  • I have no idea what I am doing
  • Django or the sqlite3 backend *should* be handling the cascade ops internally -- but isn't
What am I missing?

Simon Charette

unread,
Mar 21, 2018, 11:34:47 AM3/21/18
to Django users
Hello Anon,

Django doesn't use database level ON DELETE constraints and emulates them in Python
to dispatch pre_delete/post_delete signals. As long as you're using the ORM to perform
the deletion you shouldn't encounter constraint violations.

There's a ticket to add support for database level on_delete constraints[0].

Cheers,
Simon

[0] https://code.djangoproject.com/ticket/21961

Seven Reeds

unread,
Mar 22, 2018, 2:42:49 PM3/22/18
to Django users
Uh, am I not using the ORM?  If I am not then what must I do to get back on track?

I just realized that i didn't include the "Delete" CBV in my original post.  I do not have easy access to the code at the moment so what follows is a rough approximation of what that code is about and is prolly full of errors:

class Delete(DeleteView):
def get:
profile = Profile.objects.get(account_number=self.request.account_number)
user = user.objects.get(pk=profile.user.pk)
user.delete()

In a debugger I can stop on the "user.delete()" line and see that the profile and user objects are what I expect them to be.
Reply all
Reply to author
Forward
0 new messages