Issue: Join with subquery column alias not included in result row
Author: larsch
State: closed
Created: 2021-10-22 09:10:28

peewee version: 3.14.4

I can't figure out how to get the aliased column of the subquery out of the result. It is not present in `row.__dict__` and accessing gives `AttributeError: object has no attribute`. Below is a distilled reproduction of the issue.

Running the `query.sql()` manually with sqlite3 actually produces the expected values and columns, so the query generator works, but the column is not accessible in the result.

```python
from peewee import *

database = SqliteDatabase('join_alias.db')


class BaseModel(Model):
    class Meta:
        database = database


class Foo(BaseModel):
    id = AutoField(unique=True)
    name = TextField()


class Bar(BaseModel):
    id = AutoField(unique=True)
    foo_id = IntegerField()
    value = IntegerField(default=0)


with database:
    database.create_tables([Foo, Bar])

f1 = Foo.create(name='FooBar')
f2 = Foo.create(name='BarBaz')
f3 = Foo.create(name='BazFoo')
b1a = Bar.create(foo_id=f1.id, value=7)
b1b = Bar.create(foo_id=f1.id, value=6)
b2a = Bar.create(foo_id=f2.id, value=5)
b2c = Bar.create(foo_id=f2.id, value=8)
b3a = Bar.create(foo_id=f3.id, value=9)
b3b = Bar.create(foo_id=f3.id, value=4)

subquery = (
    Bar
    .select(Bar.foo_id, fn.SUM(Bar.value).alias('sum'))
    .group_by(Bar.foo_id))
query = (
    Foo
    .select(Foo.name, subquery.c.sum.alias('sum'))
    .join(subquery, on=(Foo.id == subquery.c.foo_id)))
for row in query.execute():
    print(row.name)
    #print(row.sum) # Foo object has no attribute 'sum'
    #row.__dict__ doesn't contain sum
```

Attempting to access `row.sum`:

```
Traceback (most recent call last):
  File "...\join_alias.py", line 47, in <module>
    print(row.sum)
AttributeError: 'Foo' object has no attribute 'sum'
```

The `Foo.__dict__` objects returned, missing the `sum` field are:

```
{'__data__': {'name': 'FooBar'}, '_dirty': set(), '__rel__': {}, 'bar': <Bar: None>}
{'__data__': {'name': 'BarBaz'}, '_dirty': set(), '__rel__': {}, 'bar': <Bar: None>}
{'__data__': {'name': 'BazFoo'}, '_dirty': set(), '__rel__': {}, 'bar': <Bar: None>}
```

The generated query is:

```sql
SELECT
    t1.name,
    t2.sum AS sum
FROM
    foo AS t1
    INNER JOIN (
        SELECT
            t3.foo_id,
            SUM(t3.value) AS sum
        FROM
            bar AS t3
        GROUP BY
            t3.foo_id
    ) AS t2 ON (t1.id = t2.foo_id)
```

and when run directly with sqlite3, gives exactly the expected result:

|name|sum|
|-|-|
|FooBar|13|
|BarBaz|13|
|BazFoo|13|


The reason for this is that Peewee is attempting to reconstruct the model-graph, so the "sum" attribute (which logically belongs to Bar) is placed in `row.bar.sum`.

Here:

```python

sq = (Bar.select(Bar.foo_id, fn.SUM(Bar.value).alias('sum'))
      .group_by(Bar.foo_id))
query = (Foo.select(Foo.name, sq.c.sum.alias('sum'))
         .join(sq, on=(Foo.id == sq.c.foo_id))
         .order_by(Foo.name))

for foo in query:
    print(foo.name, foo.bar.sum)

# BarBaz 13
# BazFoo 13
# FooBar 13
```

If you want all attributes simply put on the model being selected, specify `.objects()` in your outer query:

```python
for foo in query.objects():
    print(foo.name, foo.sum)
```

Details here: http://docs.peewee-orm.com/en/latest/peewee/relationships.html#selecting-from-multiple-sources