Как делать UPDATE для типа данных json в PosrgeSQL

Generalproger
Дата: 09.03.2015 14:13:42
Здравствуйте есть json массив param:

["123",[23,0,"12:02"]]

Требуется обновить param->1->0

UPDATE ah_library SET param->1->0 = 1;
[Err] ОШИБКА: ошибка синтаксиса (примерное положение: "->")

Как это сделать? Неужели способа кроме как вытащить весь массив param в Java и там ему заменить значение нету?
Maxim Boguk
Дата: 09.03.2015 15:33:08
Generalproger
Здравствуйте есть json массив param:

["123",[23,0,"12:02"]]

Требуется обновить param->1->0

UPDATE ah_library SET param->1->0 = 1;
[Err] ОШИБКА: ошибка синтаксиса (примерное положение: "->")

Как это сделать? Неужели способа кроме как вытащить весь массив param в Java и там ему заменить значение нету?


С т.з. базы json по большому счету просто простыня текста... так что в общем случае да - вытаскивать на приложение и там менять.
Если вам такое понадобилось делать часто - у вас неправильный дизайн базы и это поле (поля) должны быть не в json а в основной таблице.

Если сильно постараться можно попробовать Json разобрать запросом и собрать назад. Но это неудобно в общем случае.
См: тут например.

--Maxim Boguk
www.postgresql-consulting.ru
лопата
Дата: 09.03.2015 19:42:49
Generalproger,

update в базе -- это дублирование всей записи (а если джейсон килобайтный, а то и более -- то представьте себе цену)

да и редактирование json-а, как переменной, -- это ещё и разборка сборка его через присвоение его всего каким-то переменным, один -- исходной, второй -- выходной, ну и в промежутках преобразования, а не как бы хотелось -- поменять сво-во объекта по указателю, ничего не разбирая руками и т.п.. (может быть в перл его кстати дешевле будет запихать, и там надругаться -- там похожие объекты есть, надо покумекать).

т.ч. если вы используете json -- вы либо идиот, либо очень хорошо представляете себе цену этого шага. второе, очевидно, к вам пока не относится. такие дела
Generalproger
Дата: 09.03.2015 22:50:37
лопата,

Почитал по этой теме, пожалуй вы правы, в данном случае он не настолько нужен.
А в целом JSON мне кажется использовать очень удобно если редко обновлять, или выборка элемента это тоже высокая нагрузка на БД?
лопата
Дата: 10.03.2015 01:30:18
Generalproger,

есть многие штуки, которые иногда сильно ускоряют некоторые вещи, в т.ч. массивы.

кое-что можно упростить через hstore, который якобы слабее джейсона, но в плоском случае удобнее -- у него конкатенация есть. а именно -- хранение переменного число атрибутов, тем не менее индексируемого , в отличие от EAV.

для json скорее всего тоже есть ниша -- когда апдейты редки, или можно с ними смириться, в том случае, когда по json возможен какой-нито полезный функциональный индекс, частый в пользовании.

(всё от того, что доступные всяким негодяям в М-системах самопальные индексы по чему угодно нам не доступны -- нельзя повесить смешенный индекс на комбинации полей и выражений из 2-х таблиц, да и по комбинации строк одной (типа gist на ARRAY (SELECT fld FROM tbl WHERE main_id .... ) ) -- не вешается. )
Sasha Alias
Дата: 20.03.2015 11:37:06
Если нужно много работать с JSON, рекомендую установить plv8.
Для javascript / coffeescript JSON - родной тип данных, и работать с ним легко и приятно.

DROP TABLE IF EXISTS ah_library;
---
CREATE TABLE ah_library(param JSON);
---
INSERT INTO ah_library VALUES('["123",[23,0,"12:02"]]'::json);
---
CREATE OR REPLACE FUNCTION change_param(i_param JSON, i_value INTEGER) RETURNS json AS
$$
    i_param[1][0] = i_value
    return i_param
$$
LANGUAGE plcoffee SECURITY DEFINER; 
---
SELECT * FROM ah_library;
---
UPDATE ah_library SET param = change_param(param, 1);
---
SELECT * FROM ah_library;


DROP TABLE
CREATE TABLE
INSERT 0 1
CREATE FUNCTION
         param          
------------------------
 ["123",[23,0,"12:02"]]
(1 row)

UPDATE 1
         param         
-----------------------
 ["123",[1,0,"12:02"]]
(1 row)