大きなタスクを小さなピースに分割します。
ステップ 1 - CSV ファイルを読み取るだけ
ContactCSVModel.import_from_filename() と ContactCSVModel.import_from_file() の両方が csv 行を返します。データベースとの対話をスキップするには、django モデルとの対話を無効にします。これにより、タスクが大幅に高速化され、インポートされたデータが印刷されます。これは間違いなくうまくいくはずです!
CSVモデル
class ContactCSVModel(CsvModel):
first_name = CharField()
last_name = CharField()
company = CharField()
mobile = CharField()
group = DjangoModelField(Group)
contact_owner = DjangoModelField(User)
class Meta:
delimiter = "^"
あなたのコード
def process(self):
self.date_start_processing = timezone.now()
try:
# Try and import CSV
lines = ContactCSVModel.import_data(data=self.filepath, extra_fields=[
{'value': self.group_id, 'position': 5},
{'value': self.uploaded_by.id, 'position': 6}])
print lines # or use logging
self._mark_processed(self.num_records)
except Exception as e:
self._mark_failed(unicode(e))
ステップ 2 - django モデルの相互作用を有効にしますが、DB 内の既存のアイテムをチェックするために無効にします。
この機能を有効にすると、CSV のすべての行について DB にクエリを実行し、自然キーの仕様に従って既存のアイテムをチェックするため、無効にします (ソース コードを読みました)。おそらく、CSV のすべての行が固有の連絡先であることをご存知でしょう。
これは、インポート全体で DB クエリが遅いという問題がある場合に役立ちますが、インポートが大量のメモリを消費する場合には実際には役に立ちません。
class ContactCSVModel(CsvModel):
first_name = CharField()
last_name = CharField()
company = CharField()
mobile = CharField()
group = DjangoModelField(Group)
contact_owner = DjangoModelField(User)
class Meta:
delimiter = "^"
dbModel = Contact
ステップ 3 - CSV の同じサイズのチャンクをインポートする
CSVModel を使用し、Contact モデルとの対話を有効にしますが、ContactCSVModel.import_data() に小さなイテラブルを提供します。私は 500 に設定しました。必要に応じて変更してください。以下のコード サンプル (リンク) は、アイデアを得るためのものです。これを既存のコードに入れるには、少し変更する必要があります。これは、メモリ消費が問題である場合に役立ちます。
import csv
reader = csv.reader(open(self.filepath, 'rb'))
def gen_chunks(reader, chunksize=100):
"""
Chunk generator. Take a CSV `reader` and yield
`chunksize` sized slices.
"""
chunk = []
for i, line in enumerate(reader):
if (i % chunksize == 0 and i > 0):
yield chunk
del chunk[:]
chunk.append(line)
yield chunk
for chunk in gen_chunks(reader, chunksize=500):
ContactCSVModel.import_data(data=chunk, extra_fields=[
{'value': self.group_id, 'position': 5},
{'value': self.uploaded_by.id, 'position': 6}])
ステップ 4 - 大量のメモリ消費と遅い操作をターゲットにする
django-adaptors はインポート中にすべての Contact モデル インスタンスをメモリに保持し、一括挿入操作ではなく複数の単一コミットが原因で操作が遅くなるため、大きなファイルにはあまり適していません。
あなたは多少ジャンゴアダプターに縛られています。この django パッケージに依存している場合、一括挿入に切り替えることはできません。タスクマネージャーを使用して、Windows で top または htop を使用して Linux でのメモリ消費を確認します。プロセスが大量に消費され、OS がスワッピングを開始する場合は、より効率的なメモリ消費と一括挿入をオプションとして備えた別の django アドオンに切り替えてください - csv インポート用にそれらがたくさんあります。
もう 1 つのヒントは、読み取りには csv モジュールを使用し、データベースとの対話には django モデルの知識を使用することです。これは実際には難しいことではありません。全体像の個別のタスクで試してみて、それらが機能する場合はそれらをまとめてください。頑張ってください。