Подтвердить что ты не робот

Ошибка целостности на 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".

4b9b3361

Ответ 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