LoginSignup
18

More than 5 years have passed since last update.

django-import-exportのインポートがくそ遅い理由と対処

Last updated at Posted at 2016-04-13

https://github.com/django-import-export/django-import-export
https://django-import-export.readthedocs.org/en/latest/index.html

たかだか2000行程度のCSVをインポートしようとするだけで、どうしようもないぐらい処理が重たい django-import-export ではありますが、どうやら大量にDBアクセスしとる様でした。

解決策

ただひたすらにDBへのアクセスを減らせばそれなりに早くなります。
とりあえずサンプル。

from import_export.admin import ImportExportModelAdmin
from import_export import fields, resources, widgets
from import_export.instance_loaders import CachedInstanceLoader

from .models import Foo


class FooResource(resources.ModelResource):
    related_item = fields.Field(
        column_name='related_item_id',
        attribute='related_item_id',
        widget=widgets.IntegerWidget(),
    )

    class Meta:
        model = Foo
        skip_unchanged = True
        instance_loader_class = CachedInstanceLoader


class FooAdmin(ImportExportModelAdmin):
    resource_class = FooResource
    skip_admin_log = True

ForeignKeyWidget を使わない

モデルのフィールドが ForeignKey で定義されてると、ImportExportライブラリは widgets.ForeignKeyWidget を利用する様になります。

こいつがインポート時にDBへアクセスを行ってるので、 widgets.IntegerWidget に置き換えてあげると早くなりますよ。

CachedInstanceLoader を使う

インポート時に毎行 PrimaryKey の値でDBにアクセスしやがります。

ので、先にがっつり全部読んでからやってくれる CachedInstanceLoader を使うとDBへのアクセスは1回になるので素敵。

変更のないデータを無視する(skip_unchange=True を使う)

不要な UPDATE文 を実行させない様に skip_unchange=True を書いて置くと更新時は少し早くなる。

管理画面の変更ログを作らない様にする(skip_admin_log=Trueを使う)

いちいちご丁寧に大量の変更ログを作ってくれやがるので、 skip_admin_log=True で丁重にお断りしましょう。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18