ЗАПИСЬ в JSONB, нет автоматического способа?

#postgresql #jsonb

#postgresql #jsonb

Вопрос:

jsonb_build_object('a',a, 'b',b) является избыточным (не «автоматическим») и to_jsonb(row(a,b)) уродливым, потому что игнорирует имена столбцов… Неужели нет способа поступить правильно?


Примечания

Типичный запрос — это что-то вроде

 SELECT a,b, record_to_jsonb(c,d,e) as info FROM t
  

Мне нужно динамическое решение, но, чтобы проиллюстрировать, статическим решением является определение типа данных,

 CREATE TYPE mytest AS (c text, d int, e boolean);
SELECT a,b, to_jsonb(row(c,d,e)::mytest) as info FROM t; -- work fine!
  

PS: почему PostgreSQL не предлагает обратное jsonb_to_record() ?
Либо я не вижу элегантного и эффективного способа использования to_jsonb (наиболее вероятного), либо, возможно, разработчики PostgreSQL забыли концепцию ортогональности библиотечных функций… Нет никаких технических проблем для реализации хорошей record_to_jsonb() функции, как было продемонстрировано ранее такими функциями, как xmlattributes(a,b) , которая фиксирует имя и значение colunm.

Комментарии:

1. Обратное просто to_jsonb вызывается с записью. (Проблема скорее в том, что row() конструктор не позволяет вам выбирать имена столбцов — to_jsonb отлично работает со строками всей таблицы). Можете ли вы показать полный запрос, с которым вы работаете?

2. Привет @Bergi Я отредактировал с помощью обычного запроса… Можете ли вы проиллюстрировать запрос, возможно, какое-то БОКОВОЕ СОЕДИНЕНИЕ, чтобы использовать ваше предложение?

3. Пожалуйста, прокомментируйте отрицательные голоса

4. Для динамического решения, в котором вы хотели бы выбрать имена атрибутов (точно так же, как с xmlattributes ), которые вы действительно использовали jsonb_build_object бы. Я не вижу в этом ничего плохого. На самом деле проблема не в отсутствии to_jsonb функциональности, а в том, что в postgres нет простого способа создавать произвольные записи с красивыми именами столбцов.

5. вместо to_jsonb(row(a,b)) того, чтобы просто использовать select to_jsonb(r) from (select a,b from ..) r

Ответ №1:

 select a, b, to_jsonb(subq) as info
  from t
       cross join lateral (values (c, d, e)) as subq(c, d, e);
  

или короче, сокращая синтаксис ПЕРЕКРЕСТНОГО СОЕДИНЕНИЯ и используя предложение SELECT напрямую

 select a, b, to_jsonb(subq) as info
  from t, lateral (select c, d, e) subq;
  

Может ли что-то подобное больше соответствовать вашему варианту использования? Моя мысль состояла бы в том, чтобы сохранить a and b в json и позволить запрашивающему коду просто игнорировать его.

 select a, b, to_jsonb(t) - 'a' - 'b' as info
  from t
  

Комментарии:

1. Привет, Майк, запрос работает нормально (!) и, возможно, оптимизирован компилятором SQL, но это не решение проблемы PostgreSQL, это не «простой способ» для программиста выразить запрос и иметь ту же избыточность jsonb_build_object('c',c, 'd',d, 'e',e) , что и… Итак, программисты предпочтут jsonb_build_object, не так ли?

2. PS: тестирование с explain analyse такой же производительностью (интересно!) там и . to_jsonb( row(c,d,e)::dtype ) jsonb_build_object('c',c, 'd',d, 'e',e)

3. @PeterKrauss Я понимаю вашу точку зрения и добавил еще одну возможность к моему ответу.

4. Синтаксис нового решения элегантен для дополнения столбцов (!), Но затраты на производительность высоки (JSONb медленно переделывает свою структуру)… Для не дополнения и производительности лучше использовать jsonb_build_object . Я добавил в ваше первоначальное решение альтернативный синтаксис с предложением SELECT, который кажется наиболее элегантным и эффективным : правильное решение вопроса.