Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lost type of aliased column from subquery #2248

Closed
Nurbel opened this issue Aug 14, 2020 · 9 comments
Closed

Lost type of aliased column from subquery #2248

Nurbel opened this issue Aug 14, 2020 · 9 comments

Comments

@Nurbel
Copy link

Nurbel commented Aug 14, 2020

Hi,

when using aliased colums in a subquery, peewee seems to loose the type of the column

In the following script, I access a date from a subquery, with and without an alias.
Without the alias, I get a python date as expected, but with the alias, I get a string

from peewee import *
from datetime import date
DB = SqliteDatabase('/tmp/test_subquery.db')


class MyModel(Model):
    date = DateField()

    class Meta:
        database = DB


DB.create_tables([MyModel])
MyModel.replace(date=date(2020, 1, 1)).execute()

mod2 = MyModel.alias()
sub = mod2.select(mod2.date, mod2.date.alias('aliased'))
q = (MyModel.select(MyModel.date, sub.c.date, sub.c.aliased)
     .join(sub, on=(sub.c.aliased == MyModel.date))
     )

print(q.dicts().get())

{'date': datetime.date(2020, 1, 1), 'aliased': '2020-01-01'}

Am I doing something wrong? From the doc, using aliases seemed to be the recommended way to access the subquery columns

@coleifer
Copy link
Owner

That's correct, and peewee will figure it out correctly most of the time, but when you're pulling stuff up from subqueries you may need to explicitly tell peewee how to coerce it.

Did you try:

.select(MyModel.date, sub.c.date, sub.c.date, sub.c.aliased.coerce(MyModel.date.db_value))

@Nurbel
Copy link
Author

Nurbel commented Aug 14, 2020

Your proposition does not seem to work.

the best thing I managed to do was to use MyModel.date.python_value on the result

MyModel.date.python_value(row['aliased'])

@coleifer
Copy link
Owner

Whoops, I meant .coerce(MyModel.date.python_value) -- did you try that?

@Nurbel
Copy link
Author

Nurbel commented Aug 14, 2020

Yes,I tried it did not work either

@coleifer
Copy link
Owner

Sorry, I had my APIs mixed-up. I've added a new API for this case, which may change somewhat before the next release -- but this should provide a way forward for these cases that aren't covered by the existing heuristics.

The new API would be:

.select(..., subq.c.aliased.converter(callable))

And callable() would be called on the corresponding row value taken from the cursor.

@haossu
Copy link

haossu commented Jan 10, 2021

Now I don`t use subquery . But after used cast sting to int,I use alias I get string not a int value

@coleifer
Copy link
Owner

Possibly you are aliasing it to the same name as used by an existing char/text field on your model?

@haossu
Copy link

haossu commented Jan 11, 2021

Possibly you are aliasing it to the same name as used by an existing char/text field on your model?

You are right, now i use round function to cast string to decimal

@coleifer
Copy link
Owner

If you alias an expression to the name of an existing column, peewee assumes you want to use that column's conversions for the data. So you might try also just using a different name - one that doesn't coincide with an existing field.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants