1

I am using Go and "github.com/jackc/pgx/v4/pgxpool".

One of the fields in my table has json and I need to update two keys in one query.

The first problem was to update several keys at once but I think it works fine now with a nested jsonb_set.

A bigger problem is how parameter substitution works in this case.

UPDATE my_table
    SET 
        first_column=$2,
        json_column = JSONB_SET(JSONB_SET(
                     json_column::jsonb, 
                    '{first_key_name}', 
                     $3,
                     true), 
                '{second_key_name}', 
                $4,
                true),
        updated_at  = now() at time zone 'utc'
    WHERE id=$1

This yields, however, the invalid input syntax for type json error. Adding either to_jsonb() or ::jsonb around/after the parameters ($3, $4) didn't help.

Below is how the pgx library is used to pass the arguments to the query. Both key value are of string type.

err := pool.QueryRow(ctx, myQuery,
        id,
        first_column,
        first_key_value,
        second_key_value
    ).
        Scan(...)

After some experimenting, it seems that one way to make it work is to use jsonb_build_array and then get the 0-th item. That looks totally unreadable and I am almost sure there must be a simpler way to achieve this.

UPDATE my_table
    SET 
        first_column=$2,
        json_column = JSONB_SET(JSONB_SET(
                     json_column::jsonb, 
                    '{first_key_name}', 
                     jsonb_array_element(jsonb_build_array($3::text), 0), 
                     true), 
                '{second_key_name}', 
                jsonb_array_element(jsonb_build_array($4::text), 0),
                true),
        updated_at  = now() at time zone 'utc'
    WHERE id=$1

1 Answer 1

1

You could use || operator here. Initially lets say the record look like this:

{"a":"b","key2":"value2"}

After update

update dummy set j=j::jsonb||'{"a": "new_value"}
{"a":"new_value","key2":"value2"}

Remember it replaces top level keys if found otherwise create a new key. use jsonb_build_object to create json object on right side of || operator

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.