批量导入

import-export 提供了 'bulk mode' 以提高导入大型数据集的性能。

在正常操作中,import-export 会在处理数据集中的每一行时调用 instance.save()。批量模式意味着不会调用 instance.save(),而是将实例添加到临时列表中。一旦处理的行数与 batch_size 值匹配,就会调用 bulk_create()bulk_update()

如果 batch_size 设置为 None,那么 bulk_create() / bulk_update() 只有在所有行都被处理后才被调用一次。

批量删除同样支持,通过对临时对象列表应用``filter()``,并在结果查询集上调用``delete()``。

注意事项

  • 模型的``save()``方法不会被调用,``pre_save``和``post_save``信号不会被发送。

  • bulk_update() 仅在 Django 2.2 及以上版本中支持。

  • 批量操作不适用于多对多关系。

  • 注意确保在调用批量操作之前验证实例。这意味着要确保资源字段已使用正确的小部件适当声明。如果批量操作引发异常,则该批次将失败。事务也可能处于损坏状态。其他批次可能已成功持久化,这意味着您可能会有一个部分成功的导入。

  • 在批量模式下,异常不与行关联。批量操作引发的任何异常都会被记录并作为关键(非验证)错误返回(如果``raise_errors``为true则会重新抛出)。

  • 如果你使用 ForeignKeyWidget 那么这不会影响查找时的性能,因为应该会使用 QuerySet 缓存。更多信息请参见 此处

  • 如果在批量操作期间有可能对表进行并发写入,则需要考虑其潜在影响。更多信息请参考 并发写入

如需更多信息,请阅读Django文档中关于`bulk_create() <https://docs.djangoproject.com/en/stable/ref/models/querysets/#bulk-create>`_和`bulk_update() <https://docs.djangoproject.com/en/stable/ref/models/querysets/#bulk-update>`_的部分。

性能调优

如果您需要提高导入性能,请考虑以下事项。

  • 启用 use_bulk 用于批量创建、更新和删除操作(先阅读 Caveats)。

  • 如果你的导入仅创建实例(即你确定没有更新),则设置 force_init_instance = True

  • 如果你的导入正在更新或创建实例,并且你有一组可以存储在内存中的现有实例,请使用 CachedInstanceLoader

  • 默认情况下,导入行将与持久化表示进行比较,差异将存储在每个行结果中。如果不需要此差异,则使用``skip_diff = True``禁用它。

  • 将``batch_size``设置为不同的值是可行的,但测试表明将其设置为``None``总是导致在持续时间和峰值内存方面的性能更差。

测试

提供了脚本来支持批量导入的测试和基准测试。参见 批量测试