tortoise / tortoise/tortoise-orm

Join the same table twice

Open
#1,520 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
5.6k
Forks
516
Avg merge
2d 21h
Merged PRs (30d)
9

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in queryset.py around line 139 and read AwaitableQuery.resolve_filters, especially how QueryModifier.get_query_modifiers() supplies joins. Verify the behavior when a join references self.model._meta.basetable more than once, then confirm that each reference receives a distinct alias and the generated query no longer triggers the RDBMS duplicate-table error.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
database
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.