Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

partial update json field in postgres

In Postgres I have a table like this:

CREATE TABLE storehouse
(
  user_id bigint NOT NULL,
  capacity integer NOT NULL,
  storehouse json NOT NULL,
  last_modified timestamp without time zone NOT NULL,
  CONSTRAINT storehouse_pkey PRIMARY KEY (user_id)
)

And storehouse.storehouse is storing data like this:

{
    "slots":[
        {
            "slot" : 1,
            "id" : 938
        },
        {
            "slot" : 2,
            "id" : 127
        },
    ]
}

The thing is, I want to update storehouse.storehouse.slots[2], but I do not have an idea on how to do it.

I know how to alter the entire storehouse.storehouse field, but I am wondering since Postgres supports json type, it should support partial modify, otherwise that would be no difference between json type and text type. (I know json type also has type validation which is differ to text)

like image 565
bxshi Avatar asked Jan 14 '23 14:01

bxshi


1 Answers

JSON indexing and partial updates are not currently supported. The JSON support in PostgreSQL 9.2 is rudimentary, limited to validating JSON and to converting rows and arrays to JSON. Internally, json is indeed pretty much just text.

There's ongoing work for enhancements like partial updates,indexing, etc. No matter what, though, PostgreSQL won't be able to avoid rewriting the whole row when part of a JSON value changes, because that's inherent to the MVCC model of concurrency. The only way to make that possible would be to split JSON values out into multiple tuples in a side relation, like TOAST tables - something that's possible, but likely to perform poorly and that's very far from being considered at this point.

As Chris Travers points out, you can use PL/V8 functions or functions in other languages with json support like Perl or Python to extract values, then create expression indexes on those functions.

like image 61
Craig Ringer Avatar answered Jan 22 '23 20:01

Craig Ringer