python - Django REST Framework 序列化 POST 很慢

标签 python django django-rest-framework

我在 Django 2.1.1 和 Python 3.6.5 上运行,并且正在执行相当大的 POST 操作(32,000 个 JSON 对象)。我有以下几点:

模型:

class Data(models.Model):
    investigation = models.ForeignKey(Investigation)
    usage = models.FloatField()
    sector = models.CharField(max_length=100, blank=False, default='')
    cost = models.FloatField()
    demand = models.FloatField()

序列化器:
class DataSerializer(serializers.ModelSerializer):
    class Meta:
        model = Data
        fields = ('investigation', 'usage', 'sector', 'cost', 'demand')

看法:
class DataView(generics.CreateAPIView):
    def create(self, request, pk, format=None):
        data_serializer = DataSerializer(data=request.data, many=True)
        if data_serializer.is_valid():
            data_serializer.save()

问题出现在 is_valid() 和 save() 步骤中,每个步骤都会针对 32,000 个对象中的每一个触发单独的查询。

我花了很长时间研究这个问题,我猜测 is_valid() 步骤很慢,因为 N+1 查询问题,因为每次都在查找外键(尽管我可能是错的) !) 但我不知道如何在这个框架中实现 prefetch_related 方法。

save() 步骤(这是最慢的部分)显然需要在一个查询中完成(可能是一个 bulk_create),但我找不到在哪里添加 bulk_create 步骤。我已经阅读了 this question但从答案中我仍然不明智。正如问题所暗示的那样,我尝试创建一个 ListSerializer ,但对象似乎仍然被一个一个地序列化。

任何指针将不胜感激。

最佳答案

一种可能的解决方案是执行 Django ORM bulk_create()在使用序列化程序验证数据之后。您的 View 将如下所示:

class DataView(generics.CreateAPIView):
    def create(self, request, pk, format=None):
        data_serializer = DataSerializer(data=request.data, many=True)
        if data_serializer.is_valid():
            data_objects = []
            for data_object_info in data_serializer.validated_data:
                data_objects.append(Data(**data_object_info))
            Data.objects.bulk_create(data_objects)

或者只是以下,如果你想要一个单线:

Data.objects.bulk_create([Data(**params) for params in data_serializer.validated_data])

如果您不想弄乱您的 View ,那么您可以编写一个执行验证(使用序列化程序)和创建的类或方法。然后您可以在 View 中使用它。

关于python - Django REST Framework 序列化 POST 很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53364738/

相关文章:

将 def list() 添加到模型 View 集时,Django rest 框架过滤器和搜索不起作用

python - 为什么 Pycharm 的检查员提示 "d = {}"?

python - Python中不同数据类型的大小

python - 如何在 Django Rest Framework 中对外部 API 进行分页

python - 在没有模型的情况下将自定义页面添加到 django admin

python - django format_html 不支持 unicode

django - 不可哈希类型 : 'ReturnDict' drf django

python - Pandas :比前滚更快的方法?

python - QA_test 用于不同类型的 gnuradio 上的多个输出

python - 为外部/第三方库自定义日志记录