#arrays #json #postgresql
Вопрос:
Я ищу синтаксис для загрузки строк другой таблицы в соответствии со списком идентификаторов, закодированных в JSON, и возвращаю полученный запрос в виде массива объектов JSON.
Мой вариант использования-хранение простых списков ссылок в виде массивов идентификаторов в поле JSON, а не в отдельной таблице записей.
Первый вариант использования-возврат расширенного (переведенного из идентификаторов в объекты) массива JSON из ВСТАВКИ (потому что я надеюсь, что это поведение также вернется из ВСТАВКИ). Это самое близкое, что я, по-моему, получил: ничто из того, что я пробовал, не прошло успешно.
CREATE TABLE image_upload (
id SERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL,
image_filename VARCHAR(255) NOT NULL,
image_width INTEGER NOT NULL,
image_height INTEGER NOT NULL
);
CREATE TABLE image_strip (
id SERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL,
image_ids JSON NOT NULL,
updated_at TIMESTAMPTZ NOT NULL
);
INSERT INTO image_upload (created_at, image_filename, image_width, image_height)
VALUES (NOW(), 'test.png', 100, 100);
INSERT INTO image_upload (created_at, image_filename, image_width, image_height)
VALUES (NOW(), 'test2.png', 100, 100);
INSERT INTO image_strip (created_at, updated_at, image_ids)
VALUES (NOW(), NOW(), '[1,2]')
RETURNING id, created_at, updated_at,
(SELECT json_agg(iu)
FROM image_upload iu
INNER JOIN ROWS FROM(json_array_elements(image_ids)) WITH ORDINALITY AS x(id, ord)
ON x.id = iu.id
ORDER BY x.ord) AS images;
Комментарии:
1. Не делайте этого, используйте правильную таблицу отношений с внешними ключами.
2. Если вы настаиваете (и я признаю, что хранение массива облегчает упорядочивание коллекции), по крайней мере, используйте массив целых чисел (
int[]
), а не что — то в формате json, что может не быть массивом или не содержать чисел. И это на самом деле ваша проблема — ваше соединение пытается сравнитьjson
значение сint
эгером.3. Кастинг
x.id::text::int
сработал бы, но я действительно рекомендую это .4. Спасибо за совет int[] и демонстрацию @Bergi, если вы хотите опубликовать это в качестве ответа, я приму его