python - Django REST Framework 中的并行序列化?或者其他加速模型序列化的方法?

标签 python django multithreading django-rest-framework multiprocessing

我正在开发的应用程序需要通过 REST 端点向用户提供 ORM 对象列表。对象列表很大 - 一次最多 500 或 600 个(不能选择分页)。

模型看起来像这样:

class PositionItem(models.Model):
    account = models.ForeignKey(core_models.Portfolio, on_delete=models.CASCADE)
    macro_category = models.ForeignKey(MacroCategory, on_delete=models.SET_NULL, null=True)
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
    sub_category = models.ForeignKey(SubCategory, on_delete=models.SET_NULL, null=True)

我开始使用设置了 many=True 的标准 ModelSerializer,但速度非常慢 - 序列化所有对象最多需要 12 秒。我通过使用 .select_lated() 方法预取/缓存端点所需的外键,将运行时间减少了几秒钟,并通过替换 ModelSerializer 又减少了几秒钟> 使用自定义序列化器函数,仅将字段映射到字典,而无需任何验证开销。然而,它仍然很慢(6-7 秒),我想进一步优化。我考虑过尝试并行化序列化器,但在实现时遇到了一些问题。

我的自定义序列化器如下所示:

def serialize_position_record(record):

    account = record.account
    macro_category = record.macro_category
    category = record.category
    sub_category = record.sub_category

    return {
        'account': account.portfolio_id,
        'macro_category': macro_category.macro_category,
        'category': category.category,
        'sub_category': sub_category.sub_category,
        'sorting': {
            'macro_category': macro_category.sort_order,
            'category': category.sort_order,
            'sub_category': sub_category.sort_order

        }
    }

我尝试过使用进行多处理:

import multiprocessing
import models
import utils

items = models.Item.objects.select_related().filter(account__user=user)
pool = multiprocessing.Pool(4)
serialized_items = pool.map(utils.serialize_position_record, items)

但这会挂起至少 60 秒(可能更长,我在它返回任何内容之前杀死了它)。

我还尝试使用 multiprocessing.dummy API 进行线程处理:

import multiprocessing
import models
import utils

items = models.Item.objects.select_related().filter(account__user=user)
pool = multiprocessing.dummy.Pool(4)
serialized_items = pool.map(utils.serialize_position_record, items)

但我遇到了异常(exception):

Traceback (most recent call last):
  File "/Users/xx/venvs/web-portal/lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py", line 164, in __get__
    rel_obj = self.field.get_cached_value(instance)
  File "/Users/xx/venvs/web-portal/lib/python3.7/site-packages/django/db/models/fields/mixins.py", line 13, in get_cached_value
    return instance._state.fields_cache[cache_name]
KeyError: 'sub_category'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/xx/venvs/web-portal/lib/python3.7/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.UndefinedTable: relation "reports_subcategory" does not exist
LINE 1: ...", "reports_subcategory"."sort_order" FROM "reports_s...

所以我不知道该怎么办。我没有写很多并行代码——我写错了什么吗?或者除了并行化之外还有更好的方法来优化这个过程吗?我的表现已经达到上限了吗?我还使用 django-tenants,因为这是一个 Multi-Tenancy 应用程序 - 不确定这是否会导致关系不存在错误。

有什么想法吗?

最佳答案

考虑使用第三方序列化库,例如 serpymarshmallow 。两者都声称比原生 Django Rest Framework 序列化器提供了显着的速度改进。

Serpy 提供了一些 detailed benchmarks在他们的文档上。

Serialization Times According to Serpy

如果您已经熟悉 Django Rest Framework 中的序列化器,这两个库都相当直观。

关于python - Django REST Framework 中的并行序列化?或者其他加速模型序列化的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60047666/

相关文章:

c++ - 从 MFC 中的工作线程调用 Beginwaitcursor 函数

java - 如何为每个请求项创建多个线程

python - QCheckbox 检查所有其他 QCheckBoxes

python - 从字符串中删除范围内的字符

python - 轮询 celery 任务并返回显示

java - 双重检查锁定作为反模式

python - 试图制作数学游戏,但数学不起作用

python - 使用 FileField 时出现 "unindent does not match any outer indentation level"

django - 如何在 Django 中上传电影文件?

Django 区分 View 方法中的 get/post