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

时间:2021-11-28 20:28:44

Apparently after adding my new user table to the site, django_admin_log still has a FK to auth_user table. Any way to address this? I didn't see this problem in staging or locally so something odd must have taken place.

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

Traceback (most recent call last) :

回溯(最近一次通话):

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)

文件“/ app / .heroku / python / lib / python2.7 /网站/ django /核心/处理/基地。py",第115行,在get_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)

文件“/ app / .heroku / python / lib / python2.7 /网站/ newrelic-1.10.0.28 / newrelic / api / object_wrapper。第220行,调用self。kwargs _nr_instance,args)

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)

文件“/ app / .heroku / python / lib / python2.7 /网站/ newrelic-1.10.0.28 / newrelic /钩/ framework_django。py",第475行,包装在包装好的包装里(*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)

文件“/ app / .heroku / python / lib / python2.7 /网站/ django / contrib / admin /选项。py",第372行,在包装器返回self.admin_site.admin_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)

文件“/ app / .heroku / python / lib / python2.7 /网站/ django /跑龙套/修饰符。在_wrapped_view响应= view_func(请求,*args, **kwargs)中,第91行

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)

文件“/ app / .heroku / python / lib / python2.7 /网站/ django /视图/设计师/缓存。第89行,在_wrapped_view_func响应= 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)

文件“/ app / .heroku / python / lib / python2.7 /网站/ django / contrib /管理/网站。py",第202行,在内部返回视图(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)

文件“/ app / .heroku / python / lib / python2.7 /网站/ django /跑龙套/修饰符。第25行,_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)

文件“/ app / .heroku / python / lib / python2.7 /网站/ django /跑龙套/修饰符。在_wrapped_view响应= view_func(请求,*args, **kwargs)中,第91行

File "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py", line 21, in bound_func return func(self, *args2, **kwargs2)

文件“/ app / .heroku / python / lib / python2.7 /网站/ django /跑龙套/修饰符。第21行,在bound_func返回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)

文件“/ app / .heroku / python / lib / python2.7 /网站/ django / db /事务。py",第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)

文件“/ app / .heroku / python / lib / python2.7 /网站/ django / db /事务。第217行,退出self。退出(exc_value self.using)

File "/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py", line 281, in exiting commit(using=using)

文件“/ app / .heroku / python / lib / python2.7 /网站/ django / db /事务。py",第281行,在退出提交中(使用=使用)

File "/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py", line 152, in commit connection.commit()

文件“/ app / .heroku / python / lib / python2.7 /网站/ django / db /事务。py",第152行,在提交连接中。commit()

File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/init.py", line 241, in commit self._commit()

文件“/ app / .heroku / python / lib / python2.7 /网站/ django / db /后端/ init。py",第241行,在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])

文件“/ app / .heroku / python / lib / python2.7 /网站/ django / db /后端/ postgresql_psycopg2 /基地。",第242行,在_commit 6 . reaise (utils)中。IntegrityError utils.IntegrityError(*元组(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()

文件“/ app / .heroku / python / lib / python2.7 /网站/ django / db /后端/ postgresql_psycopg2 /基地。py",第240行,在_commit return self.connect .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()

文件“/ app / .heroku / python / lib / python2.7 /网站/ newrelic-1.10.0.28 / newrelic /钩/ database_dbapi2。第68行,提交返回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".

完整性错误:插入或更新表“django_admin_log”违反外键约束“django_admin_log_user_id_fkey”细节:表“auth_user”中不存在键(user_id)=(2)。

6 个解决方案

#1


18  

That because the django_admin_log table still contains a foreign key relation to the old auth_user table.

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

You need to drop this and recreate the table.

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

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

For Django < 1.7

Django < 1.7

$ heroku run python manage.py syncdb

And for Django >= 1.7

对于Django >= 1.7。

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

And that's it :)

就是这样:)

EDITED with @dustinfarris Django 1.7+ answer precision

使用@dustinfarris Django 1.7+应答精度进行编辑

#2


30  

If you run into this and you're using >=1.7:

如果你碰到这个,用>=1。7:

./manage.py dbshell

DROP TABLE django_admin_log;

and then:

然后:

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

#3


6  

If you are on Django 1.7 or later, adding a proper migration for altering the django_admin_log table is a much better option in my opinion. That way you can keep any existing log entries, which may actually be something you have use for. Doing such an alter requires that the id field is the same, e.g. has the same name etc.

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

First you will have to find out the name of the constraint, which can be done by going into the database shell:

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

./manage.py dbshell

And then describing the django_admin_log table:

然后描述django_admin_log表:

\d+ django_admin_log;

This will have the constraint in the output, something like:

这将在输出中有约束,比如:

"user_id_refs_id_c0d12874" FOREIGN KEY (user_id) REFERENCES my_custom_auth_model(id) DEFERRABLE INITIALLY DEFERRED

Where my_custom_auth_model is the name of the table where your custom auth model lives, and user_id_refs_id_c0d12874 is the name of the constraint, which you should copy for later.

my_custom_auth_model是您的自定义auth模型所在的表的名称,user_id_refs_id_c0d12874是约束的名称,您应该在以后复制它。

Next, create a new migration:

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

./manage makemigrations --empty my_custom_auth_model

I renamed my new migration (i.e. 0000_alter_admin_log_constraint.py) to have something useful instead of a datestamp in the filename. Don't use four zeros though, use whatever was assigned when creating the migration :)

我将我的新迁移(例如,0000_alter_admin_log_constraint.py)重命名为在文件名中包含一些有用的内容,而不是一个datestamp。不过,不要使用4个0,在创建迁移时使用所分配的任何东西:)

In the new migration, this is what I used for operations:

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

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'''),
]

Substitute user_id_refs_id_c0d12874 with whatever constraint name you copied previously. As you can see, the two operations and their reverses are inverses of each other, meaning you can move this migrations backwards as well.

用之前复制的约束名替换user_id_refs_id_c0d12874。正如您所看到的,这两个操作以及它们的反向是彼此的反向,这意味着您也可以将这种迁移向后移动。

Now, all you have to do is to apply the new migration:

现在,你所要做的就是应用新的迁移:

./manage.py migrate

The django_admin_log table should now be usable again, and anything in admin writing to it will work instead of failing with an IntegrityError.

django_admin_log表现在应该可以再次使用了,对它进行管理写入的任何内容都将正常工作,而不会出现完整性错误。

#4


0  

It appears as though there may have been a bad transaction as some point when you ran this, you could try fully resetting your db with:

看起来好像有一个糟糕的交易,当你运行这个时,你可以尝试完全重置你的db:

heroku pg:reset

Or you could attempt to psql into the database and examine/correct the data thats creating the issue (which is likely that its trying to insert the same user twice):

或者你可以尝试将psql插入到数据库中,检查/纠正导致问题的数据(这很可能是试图插入相同的用户两次):

heroku pg:psql

#5


0  

I think that admin app only installs django_admin_log table.

我认为管理应用程序只安装django_admin_log表。

python manage.py sqlclear admin

BEGIN;
DROP TABLE "django_admin_log";

COMMIT;

So you can also try.

你也可以试试。

python manage.py sqlclear admin | python manage.py dbshell
python manage.py syncdb

#6


0  

Delete the database and create a superuser, finally run migrate:

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

python manage.py createsuperuser    
python manage.py migrate

#1


18  

That because the django_admin_log table still contains a foreign key relation to the old auth_user table.

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

You need to drop this and recreate the table.

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

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

For Django < 1.7

Django < 1.7

$ heroku run python manage.py syncdb

And for Django >= 1.7

对于Django >= 1.7。

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

And that's it :)

就是这样:)

EDITED with @dustinfarris Django 1.7+ answer precision

使用@dustinfarris Django 1.7+应答精度进行编辑

#2


30  

If you run into this and you're using >=1.7:

如果你碰到这个,用>=1。7:

./manage.py dbshell

DROP TABLE django_admin_log;

and then:

然后:

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

#3


6  

If you are on Django 1.7 or later, adding a proper migration for altering the django_admin_log table is a much better option in my opinion. That way you can keep any existing log entries, which may actually be something you have use for. Doing such an alter requires that the id field is the same, e.g. has the same name etc.

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

First you will have to find out the name of the constraint, which can be done by going into the database shell:

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

./manage.py dbshell

And then describing the django_admin_log table:

然后描述django_admin_log表:

\d+ django_admin_log;

This will have the constraint in the output, something like:

这将在输出中有约束,比如:

"user_id_refs_id_c0d12874" FOREIGN KEY (user_id) REFERENCES my_custom_auth_model(id) DEFERRABLE INITIALLY DEFERRED

Where my_custom_auth_model is the name of the table where your custom auth model lives, and user_id_refs_id_c0d12874 is the name of the constraint, which you should copy for later.

my_custom_auth_model是您的自定义auth模型所在的表的名称,user_id_refs_id_c0d12874是约束的名称,您应该在以后复制它。

Next, create a new migration:

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

./manage makemigrations --empty my_custom_auth_model

I renamed my new migration (i.e. 0000_alter_admin_log_constraint.py) to have something useful instead of a datestamp in the filename. Don't use four zeros though, use whatever was assigned when creating the migration :)

我将我的新迁移(例如,0000_alter_admin_log_constraint.py)重命名为在文件名中包含一些有用的内容,而不是一个datestamp。不过,不要使用4个0,在创建迁移时使用所分配的任何东西:)

In the new migration, this is what I used for operations:

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

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'''),
]

Substitute user_id_refs_id_c0d12874 with whatever constraint name you copied previously. As you can see, the two operations and their reverses are inverses of each other, meaning you can move this migrations backwards as well.

用之前复制的约束名替换user_id_refs_id_c0d12874。正如您所看到的,这两个操作以及它们的反向是彼此的反向,这意味着您也可以将这种迁移向后移动。

Now, all you have to do is to apply the new migration:

现在,你所要做的就是应用新的迁移:

./manage.py migrate

The django_admin_log table should now be usable again, and anything in admin writing to it will work instead of failing with an IntegrityError.

django_admin_log表现在应该可以再次使用了,对它进行管理写入的任何内容都将正常工作,而不会出现完整性错误。

#4


0  

It appears as though there may have been a bad transaction as some point when you ran this, you could try fully resetting your db with:

看起来好像有一个糟糕的交易,当你运行这个时,你可以尝试完全重置你的db:

heroku pg:reset

Or you could attempt to psql into the database and examine/correct the data thats creating the issue (which is likely that its trying to insert the same user twice):

或者你可以尝试将psql插入到数据库中,检查/纠正导致问题的数据(这很可能是试图插入相同的用户两次):

heroku pg:psql

#5


0  

I think that admin app only installs django_admin_log table.

我认为管理应用程序只安装django_admin_log表。

python manage.py sqlclear admin

BEGIN;
DROP TABLE "django_admin_log";

COMMIT;

So you can also try.

你也可以试试。

python manage.py sqlclear admin | python manage.py dbshell
python manage.py syncdb

#6


0  

Delete the database and create a superuser, finally run migrate:

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

python manage.py createsuperuser    
python manage.py migrate