Converting LEFT OUTER JOIN query to Django orm queryset/query

后端 未结 2 1091
我寻月下人不归
我寻月下人不归 2021-02-10 00:19

Given PostgreSQL 9.2.10, Django 1.8, python 2.7.5 and the following models:

class restProdAPI(models.Model):
    rest_id = models.PositiveIntegerField(primary_ke         


        
2条回答
  •  花落未央
    2021-02-10 00:31

    Solving it with INNER JOIN

    In case you can go with only soapProdAPI's that contain corresponding restProdAPI ( in terms of your join statement -> linked by host or ip). You can try the following:

    soapProdAPI.objects.extra(
        select = {
            'rest_id'   : "app_restProdAPI.rest_id",
            'rest_host' : "app_restProdAPI.rest_host",
            'rest_ip'   : "app_restProdAPI.rest_ip",
            'rest_mode' : "app_restProdAPI.rest_mode",
            'rest_state': "app_restProdAPI.rest_state"
        },
        tables = ["app_restProdAPI"],
        where = ["app_restProdAPI.rest_host = app_soapProdAPI.soap_host \
                  OR app_restProdAPI.rest_ip = app_soapProdAPI.soap_ip"]
    )
    

    How to filter more?

    Since we are using .extra I would advice to read the docs carefully. In general we can't use .filter with some of the fields inside the select dict, because they are not part of the soapProdAPI and Django can't resolve them. We have to stick with the where kwarg in .extra, and since it's a list, we better just add another element.

        where = ["app_restProdAPI.rest_host = app_soapProdAPI.soap_host \
                  OR app_restProdAPI.rest_ip = app_soapProdAPI.soap_ip",
                 "app_restProdAPI.rest_mode=%s"
        ],
        params = ['Excluded']
    

    Repeated subquery

    If you really need all soapProdAPI's no matter if they have corresponding restProdAPI I can only think of a one ugly example where a subquery is repeated for each field you need.

    soapProdAPI.objects.extra(
        select = {
            'rest_id'   : "(select rest_id from app_restProdAPI where app_restProdAPI.rest_host = app_soapProdAPI.soap_host OR app_restProdAPI.rest_ip = app_soapProdAPI.soap_ip)",
            'rest_host' : "(select rest_host from app_restProdAPI where app_restProdAPI.rest_host = app_soapProdAPI.soap_host OR app_restProdAPI.rest_ip = app_soapProdAPI.soap_ip)",
            'rest_ip'   : "(select rest_ip from app_restProdAPI where app_restProdAPI.rest_host = app_soapProdAPI.soap_host OR app_restProdAPI.rest_ip = app_soapProdAPI.soap_ip)",
            'rest_mode' : "(select rest_mode from app_restProdAPI where app_restProdAPI.rest_host = app_soapProdAPI.soap_host OR app_restProdAPI.rest_ip = app_soapProdAPI.soap_ip)",
            'rest_state': "(select rest_state from app_restProdAPI where app_restProdAPI.rest_host = app_soapProdAPI.soap_host OR app_restProdAPI.rest_ip = app_soapProdAPI.soap_ip)"
        },
    )
    

提交回复
热议问题