Issue: UNION query breaks table mapping for selected joined objects
Author: jakedt
State: closed
Created: 2015-06-23 15:41:06

I am finding that even though the parameters come out in the same order, and the aliases are the same, union queries break the creating of children objects from multi-table selects. 

repro:

``` python
import logging
import datetime

from peewee import *
logger = logging.getLogger(__name__)
database = SqliteDatabase(':memory:')

class User(Model):
    username = CharField(unique=True)
    class Meta:
        database = database

class Tweet(Model):
    user = ForeignKeyField(User, related_name='tweets')
    message = TextField()
    created_date = DateTimeField(default=datetime.datetime.now)
    is_published = BooleanField(default=True)
    class Meta:
        database = database

def generate_data():
    database.create_tables([User, Tweet])
    for username in ['1', '2', '3']:
        new_user = User.create(username=username)
        for msg in ['hi', 'hello', 'test']:
            Tweet.create(user=new_user, message=msg)    

def test_subqueries():
    logger.debug('Without union')

    for t in Tweet.select(Tweet, User).join(User).where(Tweet.message == 'hi'):
        logger.debug('Username: %s', t.user.username)

    logger.debug('With union')

    q1 = Tweet.select(Tweet, User).join(User).where(Tweet.message == 'hi')
    q2 = Tweet.select(Tweet, User).join(User).where(Tweet.message == 'hello')
    for t in q1 | q2:
        logger.debug('Username: %s', t.user.username)       

if __name__ == '__main__':
    generate_data()
    logging.basicConfig(level=logging.DEBUG)
    test_subqueries()
```

output:

```
DEBUG:__main__:Without union
DEBUG:peewee:('SELECT "t1"."id", "t1"."user_id", "t1"."message", "t1"."created_date", "t1"."is_published", "t2"."id", "t2"."username" FROM "tweet" AS t1 INNER JOIN "user" AS t2 ON ("t1"."user_id" = "t2"."id") WHERE ("t1"."message" = ?)', [u'hi'])
DEBUG:__main__:Username: 1
DEBUG:__main__:Username: 2
DEBUG:__main__:Username: 3
DEBUG:__main__:With union
DEBUG:peewee:('SELECT "t1"."id", "t1"."user_id", "t1"."message", "t1"."created_date", "t1"."is_published", "t2"."id", "t2"."username" FROM "tweet" AS t1 INNER JOIN "user" AS t2 ON ("t1"."user_id" = "t2"."id") WHERE ("t1"."message" = ?) UNION SELECT "t3"."id", "t3"."user_id", "t3"."message", "t3"."created_date", "t3"."is_published", "t4"."id", "t4"."username" FROM "tweet" AS t3 INNER JOIN "user" AS t4 ON ("t3"."user_id" = "t4"."id") WHERE ("t3"."message" = ?)', [u'hi', u'hello'])
DEBUG:peewee:('SELECT "t1"."id", "t1"."username" FROM "user" AS t1 WHERE ("t1"."id" = ?) LIMIT 1', [1])
DEBUG:__main__:Username: 1
DEBUG:peewee:('SELECT "t1"."id", "t1"."username" FROM "user" AS t1 WHERE ("t1"."id" = ?) LIMIT 1', [1])
DEBUG:__main__:Username: 1
DEBUG:peewee:('SELECT "t1"."id", "t1"."username" FROM "user" AS t1 WHERE ("t1"."id" = ?) LIMIT 1', [2])
DEBUG:__main__:Username: 2
DEBUG:peewee:('SELECT "t1"."id", "t1"."username" FROM "user" AS t1 WHERE ("t1"."id" = ?) LIMIT 1', [2])
DEBUG:__main__:Username: 2
DEBUG:peewee:('SELECT "t1"."id", "t1"."username" FROM "user" AS t1 WHERE ("t1"."id" = ?) LIMIT 1', [3])
DEBUG:__main__:Username: 3
DEBUG:peewee:('SELECT "t1"."id", "t1"."username" FROM "user" AS t1 WHERE ("t1"."id" = ?) LIMIT 1', [3])
DEBUG:__main__:Username: 3
```


Possible solution? I can't think through the edge cases the way you can.

``` python
diff --git i/peewee.py w/peewee.py
index c3e2a5f..192e177 100644
--- i/peewee.py
+++ w/peewee.py
@@ -2756,11 +2756,16 @@ class SelectQuery(Query):
         if self._dirty or not self._qr:
             model_class = self.model_class
             query_meta = self.get_query_meta()
+
+            naive_meta = self
+            if isinstance(self, CompoundSelect):
+                naive_meta = self.lhs
+
             if self._tuples:
                 ResultWrapper = TuplesQueryResultWrapper
             elif self._dicts:
                 ResultWrapper = DictQueryResultWrapper
-            elif self._naive or not self._joins or self.verify_naive():
+            elif naive_meta._naive or not naive_meta._joins or naive_meta.verify_naive():
                 ResultWrapper = NaiveQueryResultWrapper
             elif self._aggregate_rows:
                 ResultWrapper = AggregateQueryResultWrapper
```


Hey, thanks for submitting this. My wife and I just had a baby (yay!) but I'm quite busy with being a new Dad. I'd like to fix this, though, and will hopefully be able to get to it in a few weeks.


The fix works great! Thanks and congrats!