Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLAlchemy: coalesce() returning first not NULL and non-empty result

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.

like image 802
mpiskore Avatar asked Nov 27 '25 17:11

mpiskore


1 Answers

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.

like image 194
mpiskore Avatar answered Nov 29 '25 07:11

mpiskore



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!