代码之家  ›  专栏  ›  技术社区  ›  Kai - Kazuya Ito

Django中的“查询集”有“非懒惰模式”或“严格模式”吗?

  •  1
  • Kai - Kazuya Ito  · 技术社区  · 2 年前

    当我使用 select_for_update() update() 属于 a queryset 如下所示:

    # "store/views.py"
    
    from django.db import transaction
    from .models import Person
    from django.http import HttpResponse
    
    @transaction.atomic
    def test(request):
                            # Here                           # Here
        print(Person.objects.select_for_update().filter(id=1).update(name="Tom"))
                                                      
        return HttpResponse("Test")
    

    只有 UPDATE 查询 运行时没有 SELECT FOR UPDATE 查询 如下所示*我使用 PostgreSQL 下面的日志是 PostgreSQL的查询 你可以检查一下 on PostgreSQL, how to log queries with transaction queries such as "BEGIN" and "COMMIT" :

    enter image description here

    但是,当我使用 select_for_update() update() 属于 查询集 分开再放 print(qs) 如下所示:

    # "store/views.py"
    
    from django.db import transaction
    from .models import Person
    from django.http import HttpResponse
    
    @transaction.atomic
    def test(request):
    
        qs = Person.objects.select_for_update().filter(id=1)
        print(qs) # Here
        qs.update(name="Tom")
                                                      
        return HttpResponse("Test")
    

    选择进行更新 更新 查询 按如下所示运行:

    enter image description here

    事实上,出现上面的例子是因为 QuerySet是惰性的 根据 the Django documentation 下面是:

    QuerySet是惰性的——创建QuerySet的行为不涉及 任何数据库活动。你可以整天把过滤器堆在一起, Django实际上不会运行查询,直到QuerySet 评估。

    但是,这对我来说并不简单。我只想 正常数据库行为

    现在,有没有 非惰性模式 严格模式 对于 查询集 在姜戈?

    1 回复  |  直到 2 年前
        1
  •  0
  •   willeM_ Van Onsem    2 年前

    但是,这对我来说并不简单。我只想要正常的数据库行为。

    非惰性查询集也不容易。想象一下 QuerySet 看起来像:

    Person.objects.all().filter(id=1)

    如果查询集是 渴望的 它会先拿到 全部的 Person s、 因为 Person.objects.all() ,然后获取过滤后的项,也许还会更新记录,即使根本不需要获取项。如果 s是巨大的,它甚至可能占用服务器崩溃所需的大量内存。

    例如,您可以使用强制评估 bool(…) , len(…) , list(…) ,因此:

    from django.db import transaction
    from django.http import HttpResponse
    from .models import Person
    
    
    @transaction.atomic
    def test(request):
        qs = Person.objects.filter(id=1).select_for_update()
        bool(qs)  # noqa: evaluate the queryset
        qs.update(name='Tom')       
        return HttpResponse('Test')