简体   繁体   中英

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM