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

Posted

技术标签:

【中文标题】将现有站点更新为新的 Django 1.5 用户模型后 django_admin_log 上的完整性错误【英文标题】:Integrity error on django_admin_log after updating existing site to new Django 1.5 user model 【发布时间】:2013-02-13 23:51:15 【问题描述】:

显然在将我的新用户表添加到站点后,django_admin_log 仍然有一个到 auth_user 表的 FK。有什么办法解决这个问题吗?我在分期或本地没有看到这个问题,所以一定发生了一些奇怪的事情。

回溯(最近一次通话最后一次)

文件“/app/.heroku/python/lib/python2.7/site-packages/django/core/handlers/base.py”,第 115 行,在 get_response 响应 = 回调(请求,*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 行,在包装器中 返回包装(*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 返回函数(自我,*args2,**kwargs2)

文件“/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py”,第 223 行,在内部 返回函数(*args, **kwargs)

文件“/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py”,第 217 行,在 exit 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 行,在提交中 连接.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 六.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 返回 self.connection.commit()

文件“/app/.heroku/python/lib/python2.7/site-packages/newrelic-1.10.0.28/newrelic/hooks/database_dbapi2.py”,第 68 行,在提交中 返回 self._nr_connection.commit()

IntegrityError:在表“django_admin_log”上插入或更新违反了外键约束“django_admin_log_user_id_fkey” 详细信息:表“auth_user”中不存在键 (user_id)=(2)。

【问题讨论】:

【参考方案1】:

如果您遇到这种情况并且您正在使用 >=1.7:

./manage.py dbshell

DROP TABLE django_admin_log;

然后:

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

【讨论】:

使用 1.8.2 为我工作。如果您添加了它的实际作用,那将是最好的。 对于一个带有django 1.10.1 的新项目,我按照说明进行了删除,但最后没有使用sqlimigrate 命令,而是使用了一个简单的migrate 命令。所以它就像“迁移->错误->丢弃->迁移”。 感谢您的解决方案,但它对我不起作用。它抛出错误:“CommandError:无法从应用程序'admin'中找到匹配'001'的迁移。它在INSTALLED_APPS中吗?”你能告诉我我做错了什么吗?【参考方案2】:

这是因为django_admin_log 表仍然包含与旧auth_user 表的外键关系。

您需要删除它并重新创建表。

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

对于 Django

$ heroku run python manage.py syncdb

对于 Django >= 1.7

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

就是这样:)

使用@dustinfarris Django 1.7+ 回答精度编辑

【讨论】:

【参考方案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 是您的自定义身份验证模型所在的表的名称,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 而失败。

【讨论】:

不是最简单的解决方案,但至少它将您的数据保存在管理日志中! 我认为在迁移中硬编码约束名称并不干净。这不是便携式的。 谢谢。我也觉得拥有一个迁移文件是一种帮助我的方式【参考方案4】:

当您运行此程序时,似乎有一个错误的事务,您可以尝试完全重置您的数据库:

heroku pg:reset

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

heroku pg:psql

【讨论】:

【参考方案5】:

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

【讨论】:

【参考方案6】:

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

python manage.py createsuperuser    
python manage.py migrate

【讨论】:

某些项目无法删除数据库。

以上是关于将现有站点更新为新的 Django 1.5 用户模型后 django_admin_log 上的完整性错误的主要内容,如果未能解决你的问题,请参考以下文章

Firebase App Distribution - 为新的 UDID 更新现有 IPA

从现有系统转换为新的“分区表”

将“另存为新”按钮添加到 Django 外部对象编辑弹出窗口

游戏更新会存储现有信息吗? [复制]

JS 文件未更新为新的 id 值

需要帮助为新的 Azure queueClient 版本设置 QueueMessageEncoding.Base64