Contenttypesの競合のために、MySQLデータベースにDjangoフィクスチャをロードするのに問題があります。最初に、次のようにアプリのみからデータをダンプしようとしました。
./manage.py dumpdata escola > fixture.json
私のアプリ「escola」は他のアプリケーションのテーブルを使用しているため、外部キーの問題が見逃され続けました。これに到達するまで、追加のアプリを追加し続けました。
./manage.py dumpdata contenttypes auth escola > fixture.json
問題は、データをテストフィクスチャとしてロードしようとすると、次の制約違反になります。
IntegrityError: (1062, "Duplicate entry 'escola-t23aluno' for key 2")
問題は、Django=は、フィクスチャのプライマリキー値と競合する異なるプライマリキー値を持つコンテンツタイプを動的に再作成しようとしていることです。これは、ここに記載されているバグと同じです http://code.djangoproject.com/ticket/7052
問題は、推奨される回避策は、私が既にやっていることのcontenttypesアプリをダンプすることです!?何が得られますか?それが違いを生む場合、私はここに文書化されているようにいくつかのカスタムモデルの許可を持っています: http://docs.djangoproject.com/en/dev/ref/models/options/#permissions
manage.py dumpdata --natural
は、外部キーのより永続的な表現を使用します。 In Djangoそれらは「自然キー」と呼ばれます。例えば:
Permission.codename
はPermission.id
の代わりに使用されますUser.username
はUser.id
の代わりに使用されます詳細: 「Djangoオブジェクト)のシリアル化」の自然キーセクション
dumpdata
のその他の便利な引数:
--indent=4
は人間が読めるようにします。-e sessions
セッションデータを除外-e admin
管理サイトでの管理アクションの履歴を除外-e contenttypes -e auth.Permission
は、syncdb
中に毎回スキーマから自動的に再作成されるオブジェクトを除外します。 --natural
と一緒にのみ使用してください。そうしないと、ID番号が正しく整列されない可能性があります。はい、これは本当に刺激的です。しばらくの間、フィクスチャをロードする前にcontenttypesアプリで「manage.py reset」を実行することで回避しました(ダンプされたバージョンとは異なる自動生成されたcontenttypesデータを削除するため)。それはうまくいきましたが、最終的には、面倒なフィクスチャーと放棄されたフィクスチャにうんざりして、まっすぐなSQLダンプが好まれました(もちろん、DBの移植性は失われます)。
更新-最良の答えは--natural
フラグをdumpdata
に追加します(以下の回答に記載されています)。このフラグを書いたとき、そのフラグはまだ存在していませんでした。
フィクスチャを作成するときにコンテンツタイプをスキップしてみてください。
./manage.py dumpdata --exclude contenttypes > fixture.json
単体テストでも同様の状況で機能し、コンテンツタイプに関するあなたの洞察は本当に役に立ちました!
ここでの答えはすべて古いです... 2017年の時点で、最良の答えは次のとおりです。
manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4
私はMySQLを使用していませんでしたが、代わりにライブサーバーからsqliteにいくつかのデータをインポートしました。 contenttypes
を実行する前にloaddata
アプリデータをクリアすると、トリックが実行されました。
from Django.contrib.contenttypes.models import ContentType
ContentType.objects.all().delete()
quit()
その後
python manage.py loaddata data.json
ダンプファイルを読み込む前に、単体テストからcontenttypesアプリをリセットすることにより、テストケースでこの問題を解決しました。 Carlはすでにmanage.py
コマンドを使用してこれを提案しましたが、私はcall_command
メソッドのみを使用して同じことを行います。
>>> from Django.core import management
>>> management.call_command("flush", verbosity=0, interactive=False)
>>> management.call_command("reset", "contenttypes", verbosity=0, interactive=False)
>>> management.call_command("loaddata", "full_test_data.json", verbosity=0)
full_test_data.json
フィクスチャには、残りのテストデータに対応するcontenttypesアプリダンプが含まれています。ロードする前にアプリをリセットすることにより、重複キーIntegrityError
を防ぎます。
python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth.Permission --exclude=admin.logentry --exclude=sessions.session --indent 4 > initial_data.json
これは私のために動作します。ここでは、実際のモデルのすべてを除外しています。
外部キーと多対多の関係を表すには、自然キーを使用する必要があります。さらに、session
アプリのsessions
テーブルと、logentry
アプリのadmin
テーブルを除外することをお勧めします。
Django 1.7 +
python manage.py dumpdata --natural-foreign --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json
ジャンゴ<1.7
python manage.py dumpdata --natural --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json
Django documentation によると、--natural
はバージョン1.7で非推奨になったため、代わりに--natural-foreign
オプションを使用する必要があります。
また、--natural-primary
フラグを渡すことで逆シリアル化中に計算できるため、このオブジェクトのシリアル化されたデータの主キーを省略することもできます。
python manage.py dumpdata --natural-foreign --natural-primary --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json
./manage.py dumpdata app.Model --natural-foreign
変更されます
"content_type": 123
に
"content_type": [
"app_label",
"model"
],
フィクスチャはTestCase
で動作します
私が考え出した別の可能な答えを与えるつもりです。多分それはOPを助けるでしょう、多分それは他の誰かを助けるでしょう。
多対多のリレーションシップテーブルがあります。主キーと、他のテーブルへの2つの外部キーがあります。 2つの外部キーがdifferent pkを使用してテーブルにすでにある別のエントリと同じであるフィクスチャにエントリがある場合、失敗することがわかりました。 M2Mのリレーションシップテーブルには、2つの外部キーに対して「一緒にユニーク」があります。
したがって、M2M関係が壊れている場合は、追加する外部キーを調べ、データベースを調べて、そのFKのペアが既に別のPKの下にリストされているかどうかを確認します。
私は時々前に同様のエラーに遭遇しました。必要なテーブルを作成する前にフィクスチャをロードしようとしていたことが判明しました。だから私はやった:
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py loaddata fixtures/initial_data.json
そしてそれは魅力のように働いた
それは本当に、本当に迷惑です..私は毎回これに噛まれます。
--exclude contenttypesおよび--naturalを使用してデータをダンプしようとしましたが、常に問題が発生します。
私に最適なのは、単にtruncate table Django_content_type;
syncdbとTHENがデータをロードした後。
もちろん、initial_data.jsonのオートロードではフォールボールになります。