Issue: Foreign key field is None when joining on multiple tables with CompositeKey
Author: Tiscs
State: closed
Created: 2018-02-08 13:25:53

Works fine with peewee<3.0.12., may be something wrong at line 5968 in peewee.py.

Test codes below.

``` python
import peewee

database = peewee.MySQLDatabase('auth.py', **{
    'charset': 'utf8',
    'use_unicode': True,
    'host': 'localhost',
    'port': 3306,
    'user': 'root',
    'password': '********'
})


class BaseModel(peewee.Model):

    class Meta:
        database = database


class Tenant(BaseModel):
    id = peewee.BigIntegerField(primary_key=True)

    class Meta:
        table_name = 'tenants'


class UserAccount(BaseModel):
    id = peewee.BigIntegerField(primary_key=True)
    tenant = peewee.ForeignKeyField(column_name='tenant_id', model=Tenant, field='id')
    username = peewee.CharField()

    class Meta:
        table_name = 'user_accounts'


class OAuth2Client(BaseModel):
    id = peewee.BigIntegerField(primary_key=True)
    name = peewee.CharField()

    class Meta:
        table_name = 'oauth2_clients'


class OAuth2Account(BaseModel):
    oauth2_client = peewee.ForeignKeyField(column_name='oauth2_client_id', model=OAuth2Client, field='id')
    user_account = peewee.ForeignKeyField(column_name='user_account_id', model=UserAccount, field='id')

    class Meta:
        table_name = 'oauth2_accounts'
        primary_key = peewee.CompositeKey('oauth2_client', 'user_account')


if __name__ == '__main__':
    query = OAuth2Account.select().join(OAuth2Client).switch(OAuth2Account).join(UserAccount).where(UserAccount.id == 1)
    for oa in query:
        print((oa.oauth2_client_id, oa.oauth2_client.name))
        print((oa.user_account_id, oa.user_account.username))
    query = OAuth2Account.select().join(OAuth2Client).switch(OAuth2Account).join(UserAccount).join(Tenant).where(
        UserAccount.id == 1)
    for oa in query:
        print((oa.oauth2_client_id, oa.oauth2_client.name))
        print((oa.user_account_id, oa.user_account.username))
```

What am I looking at here? What is the output of this on your computer? What's going wrong?

Possibly related commit: 6bdcd7dc3800654ba034d03b3e7dc01971388e34

-------------------

Note: you're joining on several models unnecessarily...or, you've forgotten to add them to the `select()`:

```python
# e.g.
query = OAuth2Account.select(OAuth2Account, UserAccount, OAuth2Client).join(...)
```

I've taken your code and modified it slightly w/some test data to run locally. I see the problem -- when you include the join on `Tenant` then the `UserAccount` is empty.

Failing test case

```python
    @requires_models(A, B, C)
    def test_join_issue_1482(self):
        a1 = A.create(a='a1')
        b1 = B.create(a=a1, b='b1')
        c1 = C.create(b=b1, c='c1')

        query = (C
                 .select()
                 .join(B)
                 .join(A)
                 .where(A.a == 'a1'))
        with self.assertQueryCount(3):
            accum = [(c.c, c.b.b, c.b.a.a) for c in query]

        self.assertEqual(accum, [('c1', 'b1', 'a1')])
```

The thing I'm confused about in your queries is why, if you're joining on those models and wish to access joined instances, you aren't also selecting the columns from those models? In other words, do you realize you're doing O(n) queries?

Fixed by c76f07b

Upgrade to peewee==3.0.16, the issue is fixed.

Thanks!

Actually, I want to find a `OAuth2Account` by `UserAccount.id` and `Tenant.id`, so I tried to join `Tenant` into the query.
``` python
query = OAuth2Account.select().join(OAuth2Client).switch(OAuth2Account).join(UserAccount).join(Tenant).where(UserAccount.id == 1).where(Tenant.id == 1)
```