2013-02-27 16 views
23

Apparentemente dopo aver aggiunto la mia nuova tabella utente al sito, django_admin_log ha ancora un FK nella tabella auth_user. Un modo per affrontare questo? Non ho visto questo problema nella stadiazione o localmente, quindi qualcosa di strano deve aver avuto luogo.Errore di integrità su django_admin_log dopo l'aggiornamento del sito esistente al nuovo modello utente di Django 1.5

Traceback (chiamata più recente scorso) :

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".

risposta

18

Questo perché la tabella django_admin_log contiene ancora una relazione chiave esterna alla vecchia auth_user tavolo.

È necessario rilasciare questo e ricreare la tabella.

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

per Django < 1,7

$ heroku run python manage.py syncdb 

E per Django> = 1,7

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

E questo è tutto :)

EDITED with @dustinfarris Django 1.7+ answer precision

0

Sembra come se ci può essere stato un cattivo transazione come un certo punto quando è stato eseguito questo, si potrebbe provare pienamente a reimpostare il db con :

heroku pg:reset 

Oppure si potrebbe tentare di psql nel database ed esaminare/correggere i dati di questo è la creazione del problema (che è probabile che il suo tentativo di inserire lo stesso utente due volte) :

heroku pg:psql 
0

penso che amministratore app solo installazioni tabella django_admin_log.

python manage.py sqlclear admin 

BEGIN; 
DROP TABLE "django_admin_log"; 

COMMIT; 

Quindi si può anche provare.

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

Se si esegue in questo e si sta utilizzando> = 1.7:

./manage.py dbshell 

DROP TABLE django_admin_log; 

e poi:

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

Ottima soluzione! –

+0

Ha funzionato per me utilizzando 1.8.2. Sarebbe meglio se tu aggiungessi quello che effettivamente fa. – Frankline

+0

Per un nuovo progetto con 'django 1.10.1', ho fatto il drop come notato, ma al posto del comando' sqlimigrate' alla fine, ho usato un semplice comando 'migrate'. Quindi era come "migrate-> error-> drop-> migrate". – alxs

6

Se siete su Django 1.7 o successiva, l'aggiunta di una vera e propria migrazione per alterare la tabella django_admin_log è un'opzione molto migliore a mio parere. In questo modo è possibile mantenere tutte le voci di registro esistenti, che potrebbero effettivamente essere qualcosa per cui si è utilizzati. Effettuare tale modifica richiede che il campo id sia lo stesso, ad es. ha lo stesso nome ecc.

In primo luogo si dovrà scoprire il nome del vincolo, che può essere fatto andando nella shell database:

./manage.py dbshell 

E poi descrive il django_admin_log tavolo:

\d+ django_admin_log; 

Questo avrà il vincolo nell'output, qualcosa come:

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

Dove my_custom_auth_model è il nome della tabella in cui risiede il modello di autenticazione personalizzato e user_id_refs_id_c0d12874 è il nome del vincolo, che dovresti copiare per dopo.

Successivamente, creare una nuova migrazione:

./manage makemigrations --empty my_custom_auth_model 

ho rinominato la mia nuova migrazione (vale a dire 0000_alter_admin_log_constraint.py) per avere qualcosa di utile invece di un datestamp nel nome del file. Non utilizzare quattro zeri, però, l'uso ciò che è stato assegnato al momento della creazione della migrazione :)

Nella nuova migrazione, questo è quello che ho usato per le operazioni di:

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'''), 
] 

sostituto user_id_refs_id_c0d12874 con qualsiasi nome di vincolo è stato copiato in precedenza. Come puoi vedere, le due operazioni e i loro inversi sono inverse l'una dell'altra, il che significa che puoi spostare anche queste migrazioni all'indietro.

Ora, tutto ciò che dovete fare è di applicare la nuova migrazione:

./manage.py migrate 

La tabella django_admin_log dovrebbe ora essere di nuovo utilizzabile, e tutto ciò per iscritto admin per lavorerà invece di fallire con una IntegrityError.

+0

Non è la soluzione più semplice, ma almeno salva i tuoi dati nel registro di amministrazione! – mennanov

+0

Non penso sia pulito per codificare i nomi dei vincoli nella migrazione. Questo non è portatile. –

+0

Grazie. Anch'io sento che avere un file di migrazione è un modo per averlo mi ha aiutato –

Problemi correlati