Итерация для вставки в значения - PullRequest
1 голос
/ 28 октября 2019

Я попытаюсь представить текущую настройку в виде абстрактного представления, фокусируясь на логическом подходе к пакетной вставке.

CREATE TABLE factv (id, ..other columns..);
CREATE TABLE facto (id, ..other columns..);
CREATE TABLE dims (id serial, dimensions jsonb);

2 таблицы фактов имеют одинаковые измерения, но у них естьразные столбцы.

Есть поток событий, который отправляет сообщения в таблицу, и есть функция, которая выполняется для каждой строки, логика похожа на:

CREATE OR REPLACE FUNCTION insert_event() RETURNS TRIGGER AS $$
IF event_json ->> 'type' = 'someEvent' THEN 
    WITH factv_insert AS (
      INSERT INTO factv VALUES (id,..other columns..)
      fn_createDimId,
      NEW.event_json->>..,
          ...
      RETURNING id
      )
    INSERT INTO facto VALUES (id,..other columns..)
    (select id from factv_insert),
    NEW.event_json->>..
ELSE DoSomethingElse...
END IF;
RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;

Функция, вызываемая здесь fn_createDimId просто просматривает таблицу dims и, если эти измерения не найдены, они вставляются. Если они уже есть, просто дайте мне этот идентификатор для этих измерений в качестве идентификатора для вставки этого факта.

У меня действительно есть несколько новых событий, и мне нужно получить некоторую информацию, которая нарушает правила вставкив ... значения с ERROR: more than one row returned by a subquery used as an expression

Структура события аналогична, но не ограничивается

{
    "type": "someEvent",
    "instruction": {
        "contains": {
            "id": "containerid",
            "map": {
                "50561:null:null": {
                    "productid": "50561",
                    "quantity": 3
                },
                "50562:null:null": {
                    "productid": "50562",
                    "quantity": 8

                },
                "50559:null:null": {
                    "productid": "50559",
                    "quantity": 5
                }
            }
        },
        "target": {
            "50561": "Random",
            "50562": "Random",
            "50559": "Mix",
        }
    }

}

Здесь возникают проблемы с информацией вокруг target и соответствующими величинамидля этих идентификаторов. Из события, показанного выше, мне нужно объединить и вставить в таблицу фактов:

-------|-----
target | qty
-------|-----
Random | 11
Mixed  | 5 
-------------

Если бы мне нужно было запросить информацию, я бы запустил следующее:

WITH meta_data as (
SELECT
        json_object_keys(event_json -> 'instruction' ->'target') as prodid
        ,event_json -> 'instruction' ->'target'->>json_object_keys(event_json -> 'instruction' ->'target') as target
        ,event_json -> 'instruction' ->'contains'->'map'->json_object_keys(event_json -> 'instruction' ->'contains'->'map')->>'quantity' as qty
FROM event_table ) 
select
      target,
      sum(qty::int)
from meta_data
group by target;

Я ищу решение, которое позволяет выполнять те же логические операции, но преодолевает ошибку в нескольких возвращаемых строках, в идеале - итерацию для каждого события, которое возвращает более 1 строки.

...