Integrity error on django_admin_log after updating existing site to new Django 1.5 user model
显然,在将新用户表添加到站点后,django_admin_log仍然有一个FK到auth_user表。 有没有办法解决这个问题? 我没有在升级或本地看到这个问题所以必须发生奇怪的事情。
Traceback(最近一次调用最后一次):
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".
如果你碰到这个并且你正在使用> = 1.7:
1 2 3 | ./manage.py dbshell DROP TABLE django_admin_log; |
然后:
1 | ./manage.py sqlmigrate admin 0001 | ./manage.py dbshell |
这是因为
您需要删除它并重新创建表。
1 2 | $ heroku pg:psql psql => drop table django_admin_log; |
对于Django <1.7
1 | $ heroku run python manage.py syncdb |
而对于Django> = 1.7
1 | $ ./manage.py sqlmigrate admin 0001 | heroku pg:psql |
就是这样:)
EDITED with @dustinfarris Django 1.7+ answer precision
如果您使用的是Django 1.7或更高版本,在我看来,为改变
首先,您必须找出约束的名称,这可以通过进入数据库shell来完成:
1 | ./manage.py dbshell |
然后描述
1 | \d+ django_admin_log; |
这将在输出中具有约束,例如:
1 | "user_id_refs_id_c0d12874" FOREIGN KEY (user_id) REFERENCES my_custom_auth_model(id) DEFERRABLE INITIALLY DEFERRED |
其中
接下来,创建一个新的迁移:
1 | ./manage makemigrations --empty my_custom_auth_model |
我重命名了我的新迁移(即
在新的迁移中,这是我用于操作的内容:
1 2 3 4 5 6 7 8 9 10 | 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'''), ] |
使用先前复制的任何约束名称替换
现在,您所要做的就是应用新的迁移:
1 | ./manage.py migrate |
删除数据库并创建超级用户,最后运行
1 2 | python manage.py createsuperuser python manage.py migrate |
我认为管理员应用程序只安装django_admin_log表。
1 2 3 4 5 6 | python manage.py sqlclear admin BEGIN; DROP TABLE"django_admin_log"; COMMIT; |
所以你也可以试试。
1 2 | python manage.py sqlclear admin | python manage.py dbshell python manage.py syncdb |
看起来似乎有一个糟糕的事务,因为当你运行它时,你可以尝试完全重置你的数据库:
1 | heroku pg:reset |
或者你可以尝试psql进入数据库并检查/纠正产生问题的数据(这可能是它试图插入同一个用户两次):
1 | heroku pg:psql |