weixin_42924890 2024-09-14 14:05 采纳率: 100%
浏览 4
已结题

rest-framework中model.objects.all()数据库加载问题

不知道有没有人考虑过这个问题?
在rest-framework框架中实现一个视图类,继承ModelViewSet时候,通常会构建一个queryset 代码如下:

class ProviderView(ModelViewSet):
    # GenericAPIView类成员
    queryset = Provider.objects.all()
    print(queryset)
    # 打印 queryset 的内存大小
    memory_size = sys.getsizeof(queryset)
    print(f"Memory size of queryset>>: {memory_size} bytes")
    serializer_class = ProviderSerializer
    pagination_class = LimitedPagination
    # views.APIView类成员
    permission_classes = [ProviderPermission]

无论Provider模型数据库有多少数据(测试使用 18条或者370条)打印 queryset 的内存大小总是48bytes,这是否正确?

我最原始疑惑是 django程序在启动的时会执行queryset = Provider.objects.all(),当provider表中数据非常大的时候,会不会有内存溢出的问题?
通过上面的打印信息来看,好像是不会加载所有数据到内存中的,我不是很确定,是否有人可以给个确定的答案,非常感谢。

打印信息如下:

<QuerySet [<Provider: Provider object (1)>, <Provider: Provider object (2)>, <Provider: Provider object (3)>, <Provider: Provider 
object (4)>, <Provider: Provider object (5)>, <Provider: Provider object (6)>, <Provider: Provider object (7)>, <Provider: Provider object (8)>, <Provider: Provider object (9)>, <Provider: Provider object (10)>, <Provider: Provider object (11)>, <Provider: Provider object (12)>, <Provider: Provider object (13)>, <Provider: Provider object (14)>, <Provider: Provider object (15)>, <Provider: Provider object (16)>, <Provider: Provider object (17)>, <Provider: Provider object (18)>, <Provider: Provider object (19)>, <Provider: Provider object (20)>, '...(remaining elements truncated)...']>
Memory size of queryset>>: 48 bytes
  • 写回答

1条回答 默认 最新

  • 一轮明月照丘壑 2024-09-14 14:06
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    你观察到的现象是正确的。在Django中,Model.objects.all()并不会立即加载整个数据库的数据到内存中。它实际上返回的是一个QuerySet对象,这是一个惰性执行的查询对象,只有当你在遍历它或者将它转换为列表时,它才会去数据库中获取数据。也就是说,直到你真正需要这些数据时,Django才会去数据库查询并获取数据。这就是所谓的惰性加载(Lazy Loading)。

    在你的代码中,当你打印queryset时,你实际上只是打印了QuerySet对象本身以及它所包含的数据的简要描述,并没有真正加载所有的数据到内存中。这就是为什么你看到的内存大小始终是一个固定值的原因。如果你想要查看整个QuerySet对象所包含的所有数据,你需要遍历这个QuerySet或者使用list()函数将其转换为列表。但这只有在真正需要这些数据时才会发生。

    所以,答案是:在Django中,使用Model.objects.all()并不会导致内存溢出,因为数据是惰性加载的。只有当真正需要这些数据时,Django才会去数据库中查询并获取数据。因此,你不必担心这个问题。当然,如果你的数据量非常大并且你需要在内存中处理这些数据,那么你可能需要考虑其他策略,比如分页或者使用数据库聚合等。但这与Django的惰性加载机制并不矛盾。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 9月22日
  • 已采纳回答 9月14日
  • 创建了问题 9月14日

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀