Issue: aliasing a FK prevents related objects from being populated
Author: keredson
State: closed
Created: 2016-06-13 15:02:32

aliasing a FK prevents related objects from being populated, which causes O(n) queries.

``` python
class Person(pw.Model):
  name = pw.CharField()

class Article(pw.Model):
  title = pw.CharField()
  author = pw.ForeignKeyField(db_column='author_id', rel_model=Person, to_field='id')

derek = Person.create(name='Derek')
article = Article.create(title='My Article', author=derek)

x = Article.select(Article, Person).join(Person, on=Article.author.alias('something')).first()
print x.author.name
```

causes the following sql:

``` sql
('SELECT "t1"."id", "t1"."title", "t1"."author_id", "t1"."editor_id", "t2"."id", "t2"."name", "t2"."parent_id" FROM "article" AS t1 INNER JOIN "person" AS t2 ON ("t1"."author_id" = "t2"."id")', [])
('SELECT "t1"."id", "t1"."name", "t1"."parent_id" FROM "person" AS t1 WHERE ("t1"."id" = ?) LIMIT 1 OFFSET 0', [1])
Derek
```

whereas:

``` python
x = Article.select(Article, Person).join(Person, on=Article.author).first()
print x.author.name
```

behaves correctly:

``` sql
('SELECT "t1"."id", "t1"."title", "t1"."author_id", "t1"."editor_id", "t2"."id", "t2"."name", "t2"."parent_id" FROM "article" AS t1 INNER JOIN "person" AS t2 ON ("t1"."author_id" = "t2"."id")', [])
Derek
```

it looks like the _alias column is being used questionably here https://github.com/coleifer/peewee/blob/9f46db4e722178a2bc0408a1c5c39b31e204e61a/peewee.py#L2311 which is causing it to miss the lookup here https://github.com/coleifer/peewee/blob/9f46db4e722178a2bc0408a1c5c39b31e204e61a/peewee.py#L2380.  which is assuming the model name not the alias.  confusing to me how this is supposed to work.  is the link between what's being selected and which children objects get populated just based on the model name?


Why put an alias on the column when specifying the `on` column? Seems like a pretty contrived example unless I'm misunderstanding how this applies to a larger class of bugs?


It's only contrived because I simplified it to the smallest possible example for the purpose of the bug report.  I hit it by accident in a larger query.  I worked around it by not using the alias.


Well, what's even the point of putting an aliased column in the on parameter?


I don't know that there is a point to it here in this simplified example.  But clearly it should not be doing what it's doing.  (Surprising the user with O(n) queries.)  Probably it should effectively ignore the alias, or second to that throw an exception saying you can't used aliased FKs in a join.


I should clarify: when you put an alias on the `on` column (either an expression or a field), that is treated as an instruction to Peewee to use that alias for the joined instance when reconstructing the model graph.

So, when you write `on=Article.author.alias('something')` you're clearly instructing Peewee that you want the Article's author to be accessible as "article.something".

If you go back and re-check your code, you'll see that accessing it does not result in a query:

``` python
x = Article.select(Article, Person).join(Person, on=Article.author.alias('something')).first()
print x.something.name
```


hmmm...  ok, i can get behind that.  +1


I'm relieved. Thanks for the approval.