【问题标题】:Django ORM and hitting DBDjango ORM 并击中 DB
【发布时间】:2011-08-24 18:34:13
【问题描述】:

当我做类似的事情时

我。 objects = Model.objects.all()

然后

二。 objects.filter(field_1=some_condition)

每次在第 2 步时,我都会在各种条件下点击 db。有什么方法可以在第一次操作中获取所有数据,然后只处理结果?

【问题讨论】:

    标签: django orm


    【解决方案1】:

    在评估 qs 之前,您实际上不会访问数据库,查询是 lazy

    阅读更多here

    编辑:

    重新阅读您的问题后,很明显您在询问如何在针对不同条件进行过滤时防止数据库命中。

    qs = SomeModel.objects.all()
    
    qs1 = qs.filter(some_field='some_value')
    qs2 = qs.filter(some_field='some_other_value')
    

    通常您会希望数据库为您进行过滤。

    您可以通过将 qs 转换为列表来强制对其进行评估。这将防止进一步的数据库命中,但它可能比让您的数据库返回结果更糟糕。

    qs_l = list(qs)
    qs1_l = [element for element in qs_l if element.some_field='some_value']
    qs2_l = [element for element in qs_l if element.some_field='some_other_value']
    

    【讨论】:

    • 谢谢你的另一个问题。我可以在不将 QuerySet 转换为列表的情况下点击 db 吗?或者我可以将列表转换回查询集?
    • 您无法将列表转换为查询集。您可以通过多种方式点击 db,它们列在 DTing 答案的第二个链接中。
    • 您可以通过“在这里阅读更多”链接中提到的方法来访问数据库,例如迭代、使用分区切片等。这个答案stackoverflow.com/questions/1058135/… 和相关问题可能会引起您的兴趣。
    • 如何知道我的查询正在访问数据库?
    • django_debug_toolbar 将帮助您识别 db hits
    【解决方案2】:

    当然,您每次都会点击 db。 filter() 转换为由您的数据库执行的 SQL 语句,您不能在不点击它的情况下使用 filter。因此,您可以使用 values()list(Model.objects.all()) 检索您需要的所有对象,并且按照 zeekay 的建议,使用 Python 表达式(如列表推导式)进行额外过滤。

    【讨论】:

    【解决方案3】:

    你为什么不直接做objs = Model.objects.filter(field=condition)?也就是说,一旦执行 SQL 查询,您就可以使用 Python 表达式进行进一步的过滤/处理,而不会导致额外的数据库命中。

    【讨论】:

      猜你喜欢
      • 2017-09-01
      • 2011-10-02
      • 1970-01-01
      • 2020-08-02
      • 2015-10-28
      • 1970-01-01
      • 2017-01-09
      • 2023-03-10
      • 1970-01-01
      相关资源
      最近更新 更多