Heuristics for determining whether to use python_value is incorrect if uses with CTE having same column with model
I believe the relevant changes are here: ecfa98c9f2d5d6b30f238d97928662d909f769e2

Although I would point out that changing the above to "raw_node" does not affect the outcome of the query in any case. Change the line and try it for yourself -- the value is still an int.

There is no connection, internally, between `tmp.c.id` and either `Products.id` or `Products.id.cast('text')`. Dynamic column references such as `tmp.c.id` bear no relation to any field, and the heuristic simply looks at the column names to try and determine if a dynamic column lines up with a field.

The way to handle this correctly is:

```python
Products.select(tmp.c.id.coerce(False)).with_cte(tmp).from_(tmp)
```

And in fact, without the change you referred to (`node._coerce` vs `raw_node._coerce`) this logic would not work.

So the code is correct, in my opinion. See this test for details: 0d2e81b873c6ac6fe968779c3bf18af06f5a6a47 Thanks for clarifying. Though I should say that it might be a breaking change, because it breaks my code after upgrade to newer Peewee. May be a note in CHANGELOG? > because it breaks my code after upgrade to newer Peewee

Are you sure? Yes. It is one of our company's project and upgrading peewee to master (we also had another problem that was also fixed in master), our CI just broke all over the place that I had a hard time to debug it. Probably because we make use of CTE a lot.

But indeed, changing our code to what you suggested works so it's ok for us now.  Gotcha gotcha -- I think I was confused because when testing locally, changing `node` to `raw_node` did not have any effect in the example you provided. However, there are some other reorganizations of that code that may be causing the discrepancies you're seeing.

At any rate, using the `.coerce(False)` ought to take care of it. Thanks for your comments and contributions -- it's nice to work w/someone who has a solid understanding of how peewee works.
Reproducible snippet:

```python

class Products(Model):
    id = IntegerField()

tmp = Products.select(Products.id.cast('text')).cte('tmp', columns=('id',))

# Normally, we will #join with tmp here but use #from_ instead just for demonstration purpose
Products.select(tmp.c.id).with_cte(tmp).from_(tmp)
# => [{'id': 1}] <-- should be string here instead
```

The problem is due to the change of this line:

https://github.com/coleifer/peewee/blob/178bc0155bf569c9245296e90ba5066901e208bc/peewee.py#L6483

```diff
- raw_node._coerce
+ node._coerce
```
