Django m2m产生不必要的内部联接,从而更改SQL结果

时间:2018-12-08 23:10:57

标签: django django-models many-to-many django-queryset django-orm

Django 2.1.4(类似的行为也存在于2.0.4中) 型号:

class Application(models.Model):
    # many fileds
    name = models.CharField(max_length=255)
    seers = models.ManyToManyField('Agency', through='ApplicationAgencySeer')
    parent = models.ForeignKey("self", null=True, blank=True, on_delete=SET_NULL)  

class ApplicationAgencySeer(models.Model):
    application = models.ForeignKey(Application, on_delete=models.CASCADE)
    agency = models.ForeignKey('Agency', on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)

现在我要过滤

# count 0
Application.objects.filter(seers__agency__id='c3e5ed58-a4d9-4ca6-a8f7-6793eb8e3e24').count()  # 0
# but count 1
ApplicationAgencySeer.objects.filter(agency__id='c3e5ed58-a4d9-4ca6-a8f7-6793eb8e3e24').count()  # 1
   SELECT *
   FROM "app_application"
          INNER JOIN "myapp_applicationagencyseer"
                     ON ("app_application"."id" = "app_applicationagencyseer"."application_id")
          INNER JOIN "myapp_agency"
                     ON ("app_applicationagencyseer"."agency_id" = "app_agency"."organization_ptr_id")
          INNER JOIN "myapp_agency" T4 ON ("app_agency"."organization_ptr_id" = T4."parent_id")
   WHERE T4."organization_ptr_id" = 'c3e5ed58-a4d9-4ca6-a8f7-6793eb8e3e24'

如果删除INNER JOIN "myapp_agency" T4 ON ("app_agency"."organization_ptr_id" = T4."parent_id")没问题。

为什么parent_id为什么-

我发现了该错误,也许与某些相关的问题{djangoproject>,但在6年前。我认为它已在2.1.4版本之前修复。 我该如何撰写正确的过滤器查询,或者避免这种情况。帮我,我被困住了。

   SELECT *
   FROM "myapp_application"
   WHERE NOT ("myapp_application"."id" IN (SELECT U1."application_id"
                                              FROM "myapp_applicationagencyseer" U1
                                                     INNER JOIN "myapp_agency" U2 ON (U1."agency_id" = U2."organization_ptr_id")
                                                     INNER JOIN "myapp_agency" U3 ON (U2."organization_ptr_id" = U3."parent_id")
                                              WHERE U3."organization_ptr_id" = '9e71cff4-443d-4c60-ac2d-9dcca2a9c147'))
   ORDER BY "myapp_application"."created_date" DESC;

   result

   application_id
   7d83d056-5a7d-4095-9037-98bde29a3d78    otherfields..
   7cb60afc-109d-4570-ad24-6cad6b7ddd9a    otherfields..   <-- this row error


   --return 0
   (SELECT U1."application_id"
    FROM "myapp_applicationagencyseer" U1
                INNER JOIN "myapp_agency" U2 ON (U1."agency_id" = U2."organization_ptr_id")
                INNER JOIN "myapp_agency" U3 ON (U2."organization_ptr_id" = U3."parent_id")
    WHERE U3."organization_ptr_id" = '9e71cff4-443d-4c60-ac2d-9dcca2a9c147')

   --althouth I have  myapp_applicationagencyseer
   id       created                   agency_id                                   application_id               status
   1    2018-12-10 17:41:14.272684  9e71cff4-443d-4c60-ac2d-9dcca2a9c147    7cb60afc-109d-4570-ad24-6cad6b7ddd9a    1
   2    2018-12-11 19:25:58.818000  9e71cff4-443d-4c60-ac2d-9dcca2a9c147    7cb60afc-109d-4570-ad24-6cad6b7ddd9a    0

   -- myapp_agency
   organization_ptr_id                 accreditation   parent
   aff44d42-ce81-4c3e-b6e1-056ed9351adb Null           Null
   9e71cff4-443d-4c60-ac2d-9dcca2a9c147 10АА71         Null       <-- It have Null parent

0 个答案:

没有答案