set_jsonb 不更新密钥时如何抛出错误?

How to throw an error when set_jsonb doesn't update a key?

我在 psycopg2 中 运行 这个查询:

"UPDATE accounts SET user_settings=jsonb_set(user_settings, '{{{0}}}', to_jsonb('{1}'::text, false)) WHERE accounts.id = {2};".format(
                        key, val, account_id)

它被包裹在 try/except 中。似乎当密钥更新失败时不会抛出异常。我已将 "create new key if key doesn't exist" 设置为 false。是否有可能抛出错误,以便在使用 set_jsonb() 更新密钥失败时我可以处理它?

PS。我知道我不应该使用 python 格式传递参数。这是我列表中的下一个修复程序。现在我需要弄清楚如何处理不更新的密钥。

函数 jsonb_set() 不会在键不存在时引发异常。

使用 returning 并在您的代码中检查结果:

UPDATE accounts
SET user_settings=
    jsonb_set(
        user_settings, 
        '{a_key}', 
        to_jsonb('new_value'::text),
        false)
WHERE id = 1
RETURNING user_settings->>'a_key' = 'new_value';

当且仅当密钥存在且已更新时,查询产生 true

仅当更新成功时

returning returns 一行(where 子句产生 true)。否则什么都不会退回。要有一个值来测试 union 返回集(可能为空)到失败行:

update = '''
    with u as (
        update accounts
        set user_settings = jsonb_set(
            user_settings, '{{{0}}}', to_jsonb('{1}'::text, false)
            )
        where accounts.id = {2};".format(key, val, account_id)
        returning true as updated
    )
    select updated
    from u
    union all
    select false
    order by 1 desc
'''.format(key, val, account_id)

结果将是 truefalse