tortoise / tortoise-orm

Familiar asyncio ORM for python, built with relations in mind
https://tortoise.github.io
Apache License 2.0
4.39k stars 357 forks source link

Join the same table twice #1520

Open edimedia opened 7 months ago

edimedia commented 7 months ago

Is your feature request related to a problem? Please describe. When joining two tables, the generated query contains two names of the same table and this happens only if the second join table is the same as the base table (self.model._meta.basetable) in queryset.AwaitableQuery . According to this masterpiece pypika issue, for a good join each table must have its alias, this is what is done in queryset.AwaitableQuery .resolve_filters, but as always the QueryModifier value

where_criterion, joins, having_criterion = modifier.get_query_modifiers()

joins is an array of tables, each instance of self.model._meta.basetable in this array is a self.model._meta.basetable reference. we understand that each join on this table will have the same alias.

So error from the RDBMS "the tablename appears several times"

Describe the solution you'd like The simplest solution is to make a copy each time we encounter an instance of self.model._meta.basetable to say it correctly It's a reference self.model._meta.basetable My solution is to add two lines at line 139 in queryset.py

.....
for join in joins:
   if join[0] not in self._joined_tables:
       if join[0] is self.model._meta.basetable:                  # 1
            join = (copy(self.model._meta.basetable), join[1])    # 2

       join[0].alias = "U" + str(len(self._joined_tables))
       self.query = self.query.join(join[0], how=JoinType.left_outer).on(join[1])
       self._joined_tables.append(join[0])
....

Describe alternatives you've considered Rr simply write a model manager with a new CustomAwaitableQuery which inherits from AwaitableQuery and the two lines

Additional context N/A