3

データベース内の一意性を確保しながら、大量のレコードをすばやく一括挿入できる必要があります。挿入される新しいレコードは既に解析されており、一意です。コード自体ではなく、データベース レベルで一意性を強制する方法があることを願っています。

データベースのバックエンドとして MySQL を使用しています。django が他のデータベースでこの機能をサポートしている場合、これは要件であるため、バックエンドを柔軟に変更できます。

Django での一括挿入はこのメソッドを使用しないため、save一意のフィールドと一意の一緒のフィールドを尊重しながら、一度に数百から数千のレコードを挿入するにはどうすればよいですか?


単純化した私のモデル構造は、次のようになります。

class Example(models.Model):
    Meta:
        unique_together = (('name', 'number'),)

    name = models.CharField(max_length = 50)
    number = models.CharField(max_length = 10)
    ...
    fk = models.ForeignKey(OtherModel)

編集:

データベースにまだ存在しないレコードを挿入する必要があり、既に存在するレコードは無視する必要があります。

4

2 に答える 2

1

miki725 が述べたように、現在のコードに問題はありません。bulk_createメソッドを使用していると仮定しています。bulk_create を使用するときに save() メソッドが呼び出されないのは事実ですが、フィールドの一意性は save() メソッド内で強制されません。unique_together を使用すると、テーブルの作成時に mysql の基になるテーブルに一意の制約が追加されます。

ジャンゴ:

unique_together = (('name', 'number'),)

MySQL:

UNIQUE KEY `name` (`name`,`number`)

そのため、何らかの方法 (save、bulk_insert、または生の SQL) を使用してテーブルに値を挿入すると、mysql から次の例外が発生します。

Duplicate entry 'value1-value2' for key 'name'

アップデート:

bulk_insert が行うことは、1 つのクエリですべてのデータを一度に挿入する 1 つの大きなクエリを作成することです。そのため、エントリの 1 つが重複している場合、例外がスローされ、データは挿入されません。

1- 1 つのオプションは、bulk_insert の batch_size パラメータを使用して、複数のバッチにデータを挿入し、そのうちの 1 つが失敗した場合に、そのバッチの残りのデータのみを見逃すようにすることです。(すべてのデータを挿入することの重要性と重複エントリの頻度によって異なります)

2- 別のオプションは、バルク データに for ループを記述し、バルク データを 1 つずつ挿入することです。このようにして、その 1 つの行に対してのみ例外がスローされ、残りのデータが挿入されます。これは毎回データベースにクエリを実行し、もちろん非常に遅くなります。

3- 3 番目のオプションは、一意の制約を解除し、bulk_create を使用してデータを挿入し、重複行を削除する単純なクエリを作成することです。

于 2013-03-07T05:07:28.197 に答える
0

unique_togetherDjango 自体はmeta 属性を強制しません。UNIQUEこれは、句を使用してデータベースによって強制されます。必要なだけデータを挿入でき、指定されたフィールドが一意であることが保証されます。そうでない場合は、例外が発生します (どれかはわかりません)。詳細についてunique_togetherは、ドキュメントを参照してください。

于 2013-03-07T04:27:04.720 に答える