27

新しいユーザー テーブルをサイトに追加した後、django_admin_log にはまだ auth_user テーブルへの FK が残っているようです。これに対処する方法はありますか?この問題はステージングでもローカルでも見られなかったので、何か奇妙なことが起こったに違いありません。

トレースバック(最新の呼び出しが最後) :

ファイル "/app/.heroku/python/lib/python2.7/site-packages/django/core/handlers/base.py"、115 行目、get_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 wrap(*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 応答 = 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、内部リターン ビュー (request, *args, **kwargs)

ファイル「/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py」の 25 行目、_wrapper で bound_func(*args, **kwargs) を返す

ファイル "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py"、91 行目、_wrapped_view 応答 = view_func(request, *args, **kwargs)

ファイル "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py"、21 行目、bound_func で 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 行目、exit self.exiting(exc_value, self.using)

ファイル「/app/.heroku/python/lib/python2.7/site-packages/django/db/transaction.py」、281行目、コミットの終了時(using=using)

ファイル "/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() 内

_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 で 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" に違反しています 詳細: キー (user_id)=(2) がテーブル "auth_user" に存在しません。

4

6 に答える 6

37

これに遭遇し、>=1.7 を使用している場合:

./manage.py dbshell

DROP TABLE django_admin_log;

その後:

./manage.py sqlmigrate admin 0001 | ./manage.py dbshell
于 2014-08-15T17:31:55.480 に答える
7

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ファイル名の日付スタンプの代わりに便利なものを含むように、新しい移行の名前を変更しました (つまり)。ただし、ゼロを 4 つ使用しないでください。移行の作成時に割り当てられたものを使用してください :)

新しい移行では、これが操作に使用したものです。

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にコピーした制約名に置き換えます。ご覧のとおり、2 つの操作とその逆は互いに逆です。つまり、この移行を逆方向に移動することもできます。

あとは、新しい移行を適用するだけです。

./manage.py migrate

テーブルはdjango_admin_log再び使用できるようになり、.admin で失敗する代わりに、管理者がテーブルに書き込んだものが機能しIntegrityErrorます。

于 2014-11-19T22:21:56.593 に答える
0

これを実行したある時点で、悪いトランザクションが発生した可能性があるように見えます。次のコマンドでデータベースを完全にリセットしてみてください。

heroku pg:reset

または、データベースに psql して、問題を引き起こしているデータを調べて修正することもできます (同じユーザーを 2 回挿入しようとしている可能性があります)。

heroku pg:psql
于 2013-03-03T05:02:56.920 に答える