8000 Joins being dropped when specifying multiple fields in `select_related` · Issue #46 · encode/orm · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Joins being dropped when specifying multiple fields in select_related #46
Open
@joshsharp

Description

@joshsharp

Hello again. I have an issue with using multiple tables in select_related that results in the incorrect SQL being generated.

Using these tables as an example (irrelevant fields omitted):

class User(orm.Model, BaseUser):
    pass

class Track(orm.Model):
    pass

class Post(orm.Model):
    track = orm.ForeignKey(Track, allow_null=True)
    author = orm.ForeignKey(User)

And using this query to illustrate:

posts = await Post.objects.select_related(['track','author']).all()

With this query, some JOIN expressions are dropped from the resulting SQL, so it looks something like this:

SELECT [fields] FROM track, post JOIN "user" ON "user".id = post.author

What I'd expect to see is the track table also getting a JOIN expression, rather than just appearing in the FROM. This results in the incorrect behaviour of, as far as I can make out, joining every combination of track and post together. (I didn't even realise this was valid SQL, so I've learned something.)

I believe the issue is redefining select_from here, in models.py:

def build_select_expression(self):
        tables = [self.table]
        select_from = self.table

        for item in self._select_related:
            model_cls = self.model_cls
            select_from = self.table # this is the culprit
            for part in item.split("__"):
                model_cls = model_cls.fields[part].to
                select_from = sqlalchemy.sql.join(select_from, model_cls.__table__)
                tables.append(model_cls.__table__)

I think the core problem is the redefinition of select_from on line 76, as this stops the joins from being built up each time through the loop. So if that line is removed, it seems to solve the issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0