2013-02-27 2 views
23

Scheinbar nach dem Hinzufügen meiner neuen Benutzertabelle zur Site hat django_admin_log immer noch eine FK zu auth_user-Tabelle. Irgendeine Möglichkeit, dies anzugehen? Ich habe dieses Problem nicht im Staging oder lokal gesehen, also muss etwas Seltsames passiert sein.Integritätsfehler bei django_admin_log nach der Aktualisierung der vorhandenen Site auf das neue Django 1.5-Benutzermodell

Traceback (jüngste Aufforderung zuletzt) ​​:

File "/app/.heroku/python/lib/python2.7/site-packages/django/core/handlers/base.py", line 115, in get_response response = callback(request, *callback_args, **callback_kwargs)

File "/app/.heroku/python/lib/python2.7/site-packages/newrelic-1.10.0.28/newrelic/api/object_wrapper.py", line 220, in call self._nr_instance, args, kwargs)

File "/app/.heroku/python/lib/python2.7/site-packages/newrelic-1.10.0.28/newrelic/hooks/framework_django.py", line 475, in wrapper return wrapped(*args, **kwargs)

File "/app/.heroku/python/lib/python2.7/site-packages/django/contrib/admin/options.py", line 372, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs)

File "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py", line 91, in _wrapped_view response = view_func(request, *args, **kwargs)

File "/app/.heroku/python/lib/python2.7/site-packages/django/views/decorators/cache.py", line 89, in _wrapped_view_func response = view_func(request, *args, **kwargs)

File "/app/.heroku/python/lib/python2.7/site-packages/django/contrib/admin/sites.py", line 202, in inner return view(request, *args, **kwargs)

File "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py", line 25, in _wrapper return bound_func(*args, **kwargs)

File "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py", line 91, in _wrapped_view response = view_func(request, *args, **kwargs)

File "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py", line 21, in bound_func return func(self, *args2, **kwargs2)

File "/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py", line 223, in inner return func(*args, **kwargs)

File "/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py", line 217, in exit self.exiting(exc_value, self.using)

File "/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py", line 281, in exiting commit(using=using)

File "/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py", line 152, in commit connection.commit()

File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/init.py", line 241, in commit self._commit()

File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 242, in _commit six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])

File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 240, in _commit return self.connection.commit()

File "/app/.heroku/python/lib/python2.7/site-packages/newrelic-1.10.0.28/newrelic/hooks/database_dbapi2.py", line 68, in commit return self._nr_connection.commit()

IntegrityError: insert or update on table "django_admin_log" violates foreign key constraint "django_admin_log_user_id_fkey" DETAIL: Key (user_id)=(2) is not present in table "auth_user".

Antwort

18

Das weil die django_admin_log Tabelle noch einen Fremdschlüssel Bezug auf die alten auth_user Tabelle enthält.

Sie müssen diese fallen zu lassen und die Tabelle neu zu erstellen.

$ heroku pg:psql 
psql => drop table django_admin_log; 

Für Django < 1,7

$ heroku run python manage.py syncdb 

Und für Django> = 1,7

$ ./manage.py sqlmigrate admin 0001 | heroku pg:psql 

Und das ist es :)

EDITED with @dustinfarris Django 1.7+ answer precision

0

Es scheint, als ob es eine schlechte Transaktion als irgendwann gewesen sein kann, wenn Sie dies laufen, könnten Sie versuchen, Ihre db vollständig Zurücksetzen mit :

heroku pg:reset 

Oder Sie könnten in die Datenbank psql versuchen und/prüfen, die Daten zu korrigieren, das ist das Problem zu schaffen (die, dass seine wahrscheinlich versuchen, den gleichen Benutzer zweimal einzufügen) :

heroku pg:psql 
0

Ich denke, dass Admin-App nur installiert django_admin_log Tabelle.

python manage.py sqlclear admin 

BEGIN; 
DROP TABLE "django_admin_log"; 

COMMIT; 

So können Sie auch versuchen.

python manage.py sqlclear admin | python manage.py dbshell 
python manage.py syncdb 
30

Wenn Sie in diese laufen und Sie verwenden> = 1,7:

./manage.py dbshell 

DROP TABLE django_admin_log; 

und dann:

./manage.py sqlmigrate admin 0001 | ./manage.py dbshell 
+2

Tolle Lösung! –

+0

Arbeitete für mich mit 1.8.2. Am besten wäre es, wenn Sie hinzufügen, was es tatsächlich tut. – Frankline

+0

Für ein neues Projekt mit 'django 1.10.1', habe ich die Tropfen wie erwähnt, aber anstelle den' sqlimigrate' Befehls am Ende, habe ich einen einfachen 'migrate' Befehl. Also war es wie "migrieren-> Fehler-> Drop-> migrieren". – alxs

6

Wenn Sie auf Django 1.7 oder höher, eine richtige Zugabe Migration für die Änderung der django_admin_log Tabelle ist meiner Meinung nach eine viel bessere Option. Auf diese Weise können Sie alle vorhandenen Protokolleinträge beibehalten, die möglicherweise für Sie verwendet werden. Um eine solche Änderung durchzuführen, ist es erforderlich, dass das ID-Feld das gleiche ist, z. hat den gleichen Namen usw.

Zunächst werden Sie den Namen der Einschränkung erfahren müssen, die, indem Sie in der Datenbank Shell getan werden kann:

./manage.py dbshell 

Und dann beschreibt die django_admin_log Tabelle:

\d+ django_admin_log; 

Diese wird die Einschränkung in der Ausgabe haben, etwa wie folgt:

"user_id_refs_id_c0d12874" FOREIGN KEY (user_id) REFERENCES my_custom_auth_model(id) DEFERRABLE INITIALLY DEFERRED 

Wo my_custom_auth_model ist der Name der Tabelle, wo Ihre benutzerdefinierten Auth Modell lebt und user_id_refs_id_c0d12874 ist der Name der Einschränkung, die Sie für eine spätere kopieren sollte.

Als Nächstes erstellen Sie eine neue Migration:

./manage makemigrations --empty my_custom_auth_model 

ich meine neue Migration umbenannt (das heißt 0000_alter_admin_log_constraint.py) etwas Nützliches statt einem Datumsstempel im Dateinamen haben. Sie vier Nullen allerdings nicht verwenden, verwenden, was zugewiesen wurde, wenn die Migration zu schaffen :)

In der neuen Migration, ist das, was ich für Operationen verwendet:

operations = [ 
    migrations.RunSQL(
     '''ALTER TABLE django_admin_log DROP CONSTRAINT user_id_refs_id_c0d12874''', 
     reverse_sql='''ALTER TABLE django_admin_log ADD CONSTRAINT user_id_refs_id_c0d12874 
      FOREIGN KEY (user_id) REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED'''), 
    migrations.RunSQL(
     '''ALTER TABLE django_admin_log ADD CONSTRAINT user_id_refs_id_c0d12874 
      FOREIGN KEY (user_id) REFERENCES my_custom_auth_model(id) DEFERRABLE INITIALLY DEFERRED''', 
     reverse_sql='''ALTER TABLE django_admin_log DROP CONSTRAINT user_id_refs_id_c0d12874'''), 
] 

Ersatz user_id_refs_id_c0d12874 mit dem, was Constraintname Sie kopiert vorher. Wie Sie sehen können, sind die beiden Operationen und ihre Umkehrungen Inverse zueinander, was bedeutet, dass Sie diese Migrationen auch rückwärts verschieben können.

nun alles, was Sie tun müssen, ist die neue Migration anzuwenden:

./manage.py migrate 

Die django_admin_log Tabelle jetzt sollte verwendbar sein wieder, und alles, was im Admin-Schreiben, um es statt andernfalls mit einem IntegrityError zu arbeiten.

+0

Nicht die einfachste Lösung, aber zumindest speichert es Ihre Daten im Admin-Protokoll! – mennanov

+0

Ich glaube nicht, dass es sauber ist, die Constraint-Namen in der Migration fest zu codieren. Dies ist nicht tragbar. –

+0

Danke. Ich habe auch das Gefühl, eine Migrationsdatei zu haben, um mir zu helfen –