77

In PostgreSQL 9.5, is there a way to rename an attribute in a jsonb field?

For example:

{ "nme" : "test" }

should be renamed to

{ "name" : "test"}
2

3 Answers 3

141

In UPDATE use delete (-) and concatenate (||) operators, e.g.:

create table example(id int primary key, js jsonb);
insert into example values
    (1, '{"nme": "test"}'),
    (2, '{"nme": "second test"}');

update example
set js = js - 'nme' || jsonb_build_object('name', js->'nme')
where js ? 'nme'
returning *;

 id |           js            
----+-------------------------
  1 | {"name": "test"}
  2 | {"name": "second test"}
(2 rows)
Sign up to request clarification or add additional context in comments.

6 Comments

In case somebody wonders, returning * is not mandatory for the query to work. It only causes a display (like a select) of all updated rows, that is, all rows.
@klin: I tried your query it works. But is there any way that we get ids in {} and not simply mentioned in double quotes? rextester.com/HQS81928
@PranavUnde - please ask a new question with an appropriate example.
Found the solution, first add the object with new attribute and then remove the existing attribute. something like this. update example SET js = JSONB_SET(js::JSONB, '{skill,c++}', js->'skill'->'c', true) where js->'skill' ? 'c'; update example SET js = js#-'{skill, c}' where js->'skill' ? 'c';
This is awesome, thanks! Here's an example with Rails ActiveRecord for anyone it may help: todayilearned.fyi/by/odlp/…
|
36

I used the following for handling nested attributes and skipping any json that doesn't use the old name:

UPDATE table_name
SET json_field_name = jsonb_set(json_field_name #- '{path,to,old_name}',
                                '{path,to,new_name}',
                                json_field_name#>'{path,to,old_name}')
WHERE json_field_name#>'{path,to}' ? 'old_name';

just for reference docs:

2 Comments

That worked for me, although I messed up the first entry of {path, to, old_name} it didn't seem to affect the result and I still got the right thing
@MatheusFelipe, can you please help me. I need to change LicenseDate to LicenseExpirationDate UPDATE dbo."dcp_OrgLevelEntityItems" SET "Attributes" = jsonb_set("Attributes" => '{LicenseDate}', '{LicenseExpirationDate}') WHERE "Id" = 1 Sample JSON - Column name is Attributes { "Name": "LIC", "Street": 223871, "City": 59390, "LicenseDate": "01092019" }
18

This is an old question, but still comes up high in the search rankings for this particular task. One approach that isn't all that JSON-ey but can still be a decent solution (if there is a minimal risk of key-naming collision) is to handle the field as TEXT, do a replace (could be a regex too) and then cast back to JSON.

Something like this, borrowing @klin's setup:

CREATE TABLE example(id INT PRIMARY KEY, js JSONB);
INSERT INTO example VALUES
    (1, '{"nme": "test"}'),
    (2, '{"nme": "second test"}');

UPDATE EXAMPLE
SET js = (REPLACE(js::TEXT, '"nme"', '"name"'))::JSONB
RETURNING *;

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.