I am querying for first non-empty username:
query = session.query(
Account.id.label('acc_id'),
Account.username.label('acc_username'),
User.username.label('us_username'),
User.another_username.label('also_username'),
User.email.label('email')
).join(Account.user)
And afterwords I am searching for first non-empty value among acc_username, us_username, also_username and email. In order to do this I have prepared a function to create a KeyedTuple from found id and first non-empty string value:
for q in query.all():
account_tuple = KeyedTuple(
[q.acc_id, q.acc_username or q.us_username or q.also_username or q.email or ''],
labels=_LABELS)
but instead I would rather use some form of coalesce except returning first non-empty value (in Python first not False value) instead of not NULL. Is there a proper way to do this? I would really appreciate keeping all this logic in query and not create another KeyedTuple in separate function.
I have dealt with this issue using MySQL case method in SQLAlchemy:
query = session.query(
Account.id.label('acc_id'),
case(
[
(Account.username != '', Account.username),
(User.username != '', User.username),
(User.another_username != '', User.another_username),
(User.email != '', User.email)
],
else_='')
.label('username')
.join(Account.user)
And although this may not be the proper way to achieve first nonempty string (the comparison to empty string also rejects NULL entries) it works well in this case and omits the creation of second KeyedTuple.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With