To achieve "safe value-setting" of deeply-nested fields (without having to create a new PostgreSQL function in the database), I use the following pattern: (as first mentioned here)
UPDATE "myTable" SET "myField" =
jsonb_set(COALESCE("myField", '{}'), array['depth1'],
jsonb_set(COALESCE("myField"->'depth1', '{}'), array['depth2'],
jsonb_set(COALESCE("myField"->'depth1'->'depth2', '{}'), array['depth3'],
jsonb_set(COALESCE("myField"->'depth1'->'depth2'->'depth3', '{}'), array['depth4'],
'"newValue"'
)))) WHERE "id" = 'myRowID' RETURNING *
And for those who may dislike the deeply-nested nature of the calls above, here is an alternative:
UPDATE "myTable" SET "myField" = jsonb_set(
CASE
WHEN "myField" IS NULL THEN '{"depth1": {"depth2": {"depth3": {}}}}'
WHEN "myField"->'depth1' IS NULL THEN jsonb_set("myField", array['depth1'], '{"depth2": {"depth3": {}}}')
WHEN "myField"->'depth1'->'depth2' IS NULL THEN jsonb_set("myField", array['depth1','depth2'], '{"depth3": {}}')
WHEN "myField"->'depth1'->'depth2'->'depth3' IS NULL THEN jsonb_set("myField", array['depth1','depth2','depth3'], '{}')
ELSE "myField"
END,
array['depth1','depth2','depth3','depth4'],
'"newValue"'
) WHERE "id" = 'myRowID' RETURNING *