Django filer IntegrityError at /admin/filer/folder/

375 Views Asked by At

So i have django 1.8.9 and django-filer and i started running into this problem

insert or update on table "filer_clipboard" violates foreign key constraint "filer_clipboard_user_id_2b30c76f2cd235df_fk_auth_user_id"
DETAIL:  Key (user_id)=(67) is not present in table "auth_user".

I realizes it had something to do with a new Custom User i added but looking at filer source code i saw that is should deal with it as well

class Clipboard(models.Model):
    user = models.ForeignKey(getattr(settings, 'AUTH_USER_MODEL', 'auth.User'), verbose_name=_('user'), related_name="filer_clipboards")

i have AUTH_USER_MODEL = 'authtools.User' so it still didn't make sense so i had a look at the database and i found that my old constraint was still in place (it didn't update to my new user)

postgres=# \d filer_clipboard
                          Table "public.filer_clipboard"
 Column  |  Type   |                          Modifiers                           
---------+---------+--------------------------------------------------------------
 id      | integer | not null default nextval('filer_clipboard_id_seq'::regclass)
 user_id | integer | not null
Indexes:
    "filer_clipboard_pkey" PRIMARY KEY, btree (id)
    "filer_clipboard_e8701ad4" btree (user_id)
Foreign-key constraints:
    "filer_clipboard_user_id_2b30c76f2cd235df_fk_auth_user_id" FOREIGN KEY (user_id) REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED
Referenced by:
    TABLE "filer_clipboarditem" CONSTRAINT "filer_clipb_clipboard_id_335d159e1aea2cdc_fk_filer_clipboard_id" FOREIGN KEY (clipboard_id) REFERENCES filer_clipboard(id) DEFERRABLE INITIALLY DEFERRED

Any ideas on how i can fix this? Resorting to SQL to remove the constraints and add the new one doesn't seem like the best approach.

1

There are 1 best solutions below

0
On BEST ANSWER

setting db_constraint=False in all user foreign keys in filer code base, applying the migration and then removing it again or setting it to db_constraint=True (since there are implications https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.ForeignKey.db_constraint) automatically creates the new constraint that i need.

This is much better then writing sql manually since django does it for you.

I am still testing but so far its working no more error

UPDATE:

i add to write a datamigration with RUNSQL because of django_admin_log entries that were pointing to the wrong user still:

operations = [
    migrations.RunSQL("BEGIN;"),
    migrations.RunSQL(
        "ALTER TABLE django_admin_log DROP CONSTRAINT "
        "django_admin_log_user_id_52fdd58701c5f563_fk_auth_user_id"
    ),
    migrations.RunSQL(
        "ALTER TABLE django_admin_log ADD CONSTRAINT "
        "django_admin_log_user_id_52fdd58701c5f563_fk_authtools_user_id "
        "foreign key (user_id) references authtools_user(id) "
        "DEFERRABLE INITIALLY DEFERRED"
    ),
    migrations.RunSQL("COMMIT;"),
]

After applying this to the affected db and fixing it, delete this code so that it can run on a fresh database without throwing a does not exist exception.