将现有站点更新为新的 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