Ошибка целостности на django_admin_log после обновления существующего сайта до новой пользовательской модели Django 1.5
По-видимому, после добавления моей новой пользовательской таблицы на сайт django_admin_log все еще имеет таблицу FK для auth_user. Любой способ решить эту проблему? Я не видел эту проблему в постановке или локально, поэтому должно было произойти нечто странное.
Traceback (последний последний вызов) :
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/core/handlers/base.py", строка 115, в get_response response = callback (запрос, * callback_args, ** callback_kwargs)
Файл "/app/.heroku/python/lib/python2.7/site-packages/newrelic-1.10.0.28/newrelic/api/object_wrapper.py", строка 220, в вызов self._nr_instance, args, kwargs)
Файл "/app/.heroku/python/lib/python2.7/site-packages/newrelic-1.10.0.28/newrelic/hooks/framework_django.py", строка 475, в обертке return wrapped (* args, ** kwargs)
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/contrib/admin/options.py", строка 372, в обертке return self.admin_site.admin_view (view) (* args, ** kwargs)
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py", строка 91, в _wrapped_view response = view_func (запрос, * args, ** kwargs)
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/views/decorators/cache.py", строка 89, в _wrapped_view_func response = view_func (запрос, * args, ** kwargs)
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/contrib/admin/sites.py", строка 202, внутри return (запрос, * args, ** kwargs)
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py", строка 25, в _wrapper return bound_func (* args, ** kwargs)
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py", строка 91, в _wrapped_view response = view_func (запрос, * args, ** kwargs)
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py", строка 21, в bound_func return func (self, * args2, ** kwargs2)
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py", строка 223, внутри return func (* args, ** kwargs)
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py", строка 217, в выход self.exiting(exc_value, self.using)
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py", строка 281, в выходе фиксации (с использованием = используя)
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py", строка 152, в фиксации connection.commit()
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/ init.py", строка 241, в фиксации self._commit()
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", строка 242, в _commit six.reraise(utils.IntegrityError, utils.IntegrityError(* tuple (e.args)), sys.exc_info() [2])
Файл "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", строка 240, в _commit return self.connection.commit()
Файл "/app/.heroku/python/lib/python2.7/site-packages/newrelic-1.10.0.28/newrelic/hooks/database_dbapi2.py", строка 68, в commit return self._nr_connection.commit()
IntegrityError: вставка или обновление в таблице "django_admin_log" нарушает ограничение внешнего ключа "django_admin_log_user_id_fkey" ДЕТАЛИ: Ключ (user_id) = (2) отсутствует в таблице "auth_user".
Ответы
Ответ 1
Это потому, что таблица django_admin_log
по-прежнему содержит отношение внешнего ключа к старой таблице auth_user
.
Вам нужно отбросить это и воссоздать таблицу.
$ heroku pg:psql
psql => drop table django_admin_log;
Для Django < 1.7
$ heroku run python manage.py syncdb
И для Django >= 1.7
$ ./manage.py sqlmigrate admin 0001 | heroku pg:psql
И что это:)
ИЗМЕНИТЬ с точностью @dustinfarris Django 1.7+
Ответ 2
Если вы столкнулись с этим, и вы используете >= 1.7:
./manage.py dbshell
DROP TABLE django_admin_log;
а затем:
./manage.py sqlmigrate admin 0001 | ./manage.py dbshell
Ответ 3
Если вы используете Django 1.7 или более позднюю версию, добавление надлежащей миграции для изменения таблицы django_admin_log
является гораздо лучшим вариантом, на мой взгляд. Таким образом, вы можете сохранить любые существующие записи в журнале, которые могут фактически быть тем, что вы используете. Выполнение такого изменения требует, чтобы поле id было одинаковым, например. имеет то же имя и т.д.
Сначала вам нужно будет узнать имя ограничения, которое можно сделать, перейдя в оболочку базы данных:
./manage.py dbshell
И затем описывая таблицу django_admin_log
:
\d+ django_admin_log;
Это будет иметь ограничение на выходе, что-то вроде:
"user_id_refs_id_c0d12874" FOREIGN KEY (user_id) REFERENCES my_custom_auth_model(id) DEFERRABLE INITIALLY DEFERRED
Где my_custom_auth_model
- это имя таблицы, в которой находится ваша пользовательская модель auth, а user_id_refs_id_c0d12874
- это имя ограничения, которое вы должны скопировать позже.
Затем создайте новую миграцию:
./manage makemigrations --empty my_custom_auth_model
Я переименовал новую миграцию (т.е. 0000_alter_admin_log_constraint.py
), чтобы иметь что-то полезное вместо datestamp в имени файла. Не используйте четыре нуля, но используйте все, что было назначено при создании переноса:)
В новой миграции это то, что я использовал для операций:
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'''),
]
Замените user_id_refs_id_c0d12874
на любое имя ограничения, которое вы скопировали ранее. Как вы можете видеть, две операции и их обратные являются обратными друг к другу, что означает, что вы также можете перемещать эти миграции назад.
Теперь вам нужно всего лишь применить новую миграцию:
./manage.py migrate
Теперь таблица django_admin_log
должна быть снова использована, и все, что написано в администраторе, будет работать вместо отказа с помощью IntegrityError
.
Ответ 4
Похоже, что, возможно, была некорректная транзакция, когда вы ее запускали, вы можете попробовать полностью сбросить свой db с помощью:
heroku pg:reset
Или вы можете попытаться загрузить psql в базу данных и проверить/исправить данные, которые создают проблему (что, скорее всего, пытается дважды вставить одного и того же пользователя):
heroku pg:psql
Ответ 5
Я думаю, что приложение admin только устанавливает таблицу django_admin_log.
python manage.py sqlclear admin
BEGIN;
DROP TABLE "django_admin_log";
COMMIT;
Итак, вы также можете попробовать.
python manage.py sqlclear admin | python manage.py dbshell
python manage.py syncdb