将现有站点更新为新的Django 1.5用户模型后,django_admin_log上的完整性错误

时间:2013-02-27 23:23:09

标签: django django-1.5

显然,在将新用户表添加到站点后,django_admin_log仍然有一个FK到auth_user表。有没有办法解决这个问题?我没有在升级或本地看到这个问题所以必须发生奇怪的事情。

回溯(最近一次致电最后一次)

  

文件“/app/.heroku/python/lib/python2.7/site-packages/django/core/handlers/base.py”,第115行,在get_response中       response = callback(request,* 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(request,* args,** kwargs)

     

文件“/app/.heroku/python/lib/python2.7/site-packages/django/views/decorators/cache.py”,第89行,在_wrapped_view_func中       response = view_func(request,* args,** kwargs)

     

文件“/app/.heroku/python/lib/python2.7/site-packages/django/contrib/admin/sites.py”,第202行,内部       返回视图(请求,* 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(request,* 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行,提交       return self._nr_connection.commit()

     

IntegrityError:在表“django_admin_log”上插入或更新违反外键约束“django_admin_log_user_id_fkey”   DETAIL:表(“auth_user”)中没有Key(user_id)=(2)。

6 个答案:

答案 0 :(得分:32)

如果您碰到这个并且您正在使用> = 1.7:

./manage.py dbshell

DROP TABLE django_admin_log;

然后:

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

答案 1 :(得分:20)

那是因为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 :(得分:6)

如果您使用的是Django 1.7或更高版本,在我看来,为改变django_admin_log表添加适当的迁移是一个更好的选择。这样你就可以保留任何现有的日志条目,这可能实际上是你用过的东西。进行这样的改变要求id字段是相同的,例如,具有相同的名称等。

首先,你必须找出约束的名称,这可以通过进入数据库shell来完成:

./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是您的自定义身份验证模型所在的表的名称,user_id_refs_id_c0d12874是约束的名称,您应该将其复制以供日后使用。

接下来,创建一个新的迁移:

./manage makemigrations --empty my_custom_auth_model

我重新命名了我的新迁移(即0000_alter_admin_log_constraint.py),以便在文件名中使用有用的内容而不是日期戳。不要使用四个零,使用创建迁移时分配的任何内容:)

在新迁移中,这是我用于操作的内容:

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失败。

答案 3 :(得分:0)

看起来似乎有一个糟糕的事务,因为当你运行它时,你可以尝试完全重置你的数据库:

heroku pg:reset

或者您可以尝试将psql导入数据库并检查/更正产生问题的数据(可能是它尝试将同一用户插入两次):

heroku pg:psql

答案 4 :(得分:0)

我认为管理员应用只会安装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

答案 5 :(得分:0)

删除数据库并创建超级用户,最后运行migrate

python manage.py createsuperuser    
python manage.py migrate