Составные типы с pg-promise

Вот пример кода:

battle.heroes = [{ id: hero.id, name: hero.name }]; //This is my array I want to insert
await db.one('INSERT INTO battles(mode, params, heroes) VALUES(${mode}, ${params}, ${heroes}) RETURNING id', {
    mode: battle.mode,
    params: battle.params,
    heroes: battle.heroes,
});

Тип PostgreSQL 'hero_info':

id int4
name varchar

person Arhimondus    schedule 01.05.2017    source источник


Ответы (1)


Представьте каждый элемент массива с помощью форматирования пользовательского типа, либо путем расширения существующие объекты с rawType и toPostgres или используя свой собственный тип, как показано ниже:

const hero = (id, name) => ({
   rawType: true,
   toPostgres: () => pgp.as.format('($1, $2)::hero_info', [id, name])
});

Пример использования:

const heroes = [hero(1, 'first'), hero(2, 'second')];

await db.one('INSERT INTO battles(mode, params, heroes) VALUES(${mode}, ${params}, ${heroes}) RETURNING id', {
    mode: battle.mode,
    params: battle.params,
    heroes
});

Для приведенного выше кода ваш массив heros будет правильно отформатирован как:

array[(1, 'first')::hero_info, (2, 'second')::hero_info]

person vitaly-t    schedule 01.05.2017
comment
И еще вопрос здесь. Если я хочу выбрать этот массив из db. Как я могу сопоставить его, чтобы получить JS-представление данных вместо строки? Я получаю что-то вроде {(1,HeroName1),(2,HeroName2)} для каждого значения. - person Arhimondus; 02.05.2017
comment
@Arhimondus Их называют кортежами, также известными как кошмар, с которыми довольно сложно иметь дело при обратном чтении данных. Это совершенно новый вопрос, и более важный, чем этот. Поищите в StackOverflow, там много об этом. И это предмет вне pg-promise. - person vitaly-t; 02.05.2017
comment
@Arhimondus, насколько я знаю, нет хороших решений для кортежей. И никогда не будет, потому что с ними слишком неудобно работать, и они считаются устаревшим подходом. В настоящее время разработчики используют JSON вместо кортежей. Кортежи теперь просто наследие. - person vitaly-t; 02.05.2017
comment
Синтаксис для форматирования пользовательского типа был обновлен, так как он изменился в v6.5.0. - person vitaly-t; 18.08.2017
comment
@vitaly-t Почему вы думаете, что пользовательские типы в postgres устарели? У них есть некоторые преимущества перед JSON: особенно скорость и безопасность типов (на уровне БД). - person TmTron; 16.11.2019
comment
@TmTron Начиная с версии 10 PostgreSQL, все внимание было сосредоточено на дальнейшем улучшении и оптимизации обработки JSON, которая теперь (v12) находится на другом уровне. Кортежи теперь немного устарели, плюс они создают ряд препятствий при работе с ними из-за запутанной сериализации. В общем, JSON - это путь;) - person vitaly-t; 16.11.2019
comment
@vitaly-t причина этого в том, что JSON просто новый и в нем отсутствует множество функций. С другой стороны, кортежи существуют уже давно и останутся. Что использовать, зависит от варианта использования. например для больших таблиц временных рядов использование JSON просто убьет вашу производительность. - person TmTron; 16.11.2019
comment
@TmTron Это все индивидуальный выбор. В настоящее время я занимаюсь разработкой PostgreSQL только под Node.js, где работа с кортежами превращается в кошмар, так как для них нет нормального десериализатора, а с JSON все просто работает. - person vitaly-t; 16.11.2019