Django CRUD 操作用于多个记录 - transaction.atomic vs bulk_create



我有一个 Django 1.10 模型和一个简单的模型:

我有一个简单的 REST 端点,专为测试目的而设计:

@api_view(['POST'])
@transaction.atomic
def r_test(request):
for record in request.data:
serializer = TestSerializer(data = record)
if serializer.is_valid():
serializer.save()

。对于一条 100 条记录,执行需要 9 秒(太慢(。

如果我按以下方式重写它,它会立即执行。

@api_view(['POST'])
def r_test(request):
obj_list = []
for record in request.data:
obj = Test(field1 = record['field1'])
obj_list.append(obj)
Test.objects.bulk_create(obj_list)

困扰我的是,我已经在许多来源中读到将函数包装到事务中(我通过添加装饰器@transaction.atomic(将在多个操作的情况下显着改善插入操作。但我现在看不到这一点。

所以问题是,只有bulk_create((为插入大数据提供了超快的速度,还是我在transaction.atomic做错了什么?

更新:此外,我ATOMIC_REQUESTS设置中设置为True。顺便说一句,可能是设置有问题吗?比如说,Debug = True 阻碍了 Django 在单个事务中执行查询?

更新 2我已经尝试了两种方式使用装饰器和将 for 循环包装在with transaction.atomic():中.而且我仍然只观察到即时执行bulk_create()

更新 3.我的数据库是 MySQL

事务通常会加快插入过程。由于您已经由于ATOMIC_REQUESTS = True而处于事务中,因此在使用@transaction.atomic()时不会注意到差异。事务更快的主要原因是提交需要时间。在没有事务的情况下,Django 使用自动提交模式,因此每个查询都会导致提交。

在性能方面,交易不是灵丹妙药。您仍在执行 100 次查询和 100 次数据库往返。即使您的数据库在同一系统上运行,也需要一些时间。这就是bulk_create发挥作用的地方。它执行单个查询以一次插入所有数据。您刚刚为自己节省了 99 次数据库往返。这比交易引起的任何加速都重要得多。

djangorestframework,对吧?我认为你应该先改进你的 api 功能:

def r_test(request):
serializer = TestSerializer(data=request.data, many=True)
if serializer.is_valid():
serializer.save()

再试一次。

最新更新