Django m2m создает ненужное внутреннее соединение, которое меняет результат SQL - PullRequest
0 голосов
/ 09 декабря 2018

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 почему-почему

Я обнаружил ошибку, может быть, это связано с <<a href="https://code.djangoproject.com/ticket/20535" rel="nofollow noreferrer"> 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
...