Использование Postgres FK из jsonb с помощью Hasura?

#postgresql #graphql #jsonb #hasura

#postgresql #graphql #jsonb #hasura

Вопрос:

У нас есть внешние ключи внутри большого двоичного объекта json в postgres. Мы присоединяемся к ним следующим образом:

 SELECT f.id, b.id FROM foo AS f
  LEFT JOIN bar AS b ON f.data -> 'baz' ->> 'barId' = text(b.id)
  

Сейчас я пытаюсь использовать Hasura для выполнения запросов som graphql, и они мне нужны как объектные отношения. В пользовательском интерфейсе я могу только попытаться вручную добавить отношения с обычными столбцами, а не с вложенными данными json:

введите описание изображения здесь

Возможно ли вообще получить отношения graphql таким образом?

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

1. Вы можете использовать «вычисляемое поле» Hasura для добавления этой связи. Ознакомьтесь с документами здесь: hasura.io/docs/1.0/graphql/core/schema/… Посмотрите на те части документации, где вычисляемые поля возвращают типы «таблица».

2. Вы можете увидеть пример использования «вычисляемого поля» здесь: github.com/hasura/graphql-engine/issues /…

Ответ №1:

Я получил ответ в комментариях, спасибо @iamnat. Я просто приведу здесь свой пример для наглядности, так как я все еще немного боролся:

Супер простая схема и данные как таковые:

 CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE foo
(
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name text,
    data jsonb NOT NULL
);

CREATE TABLE bar
(
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name text,
);

WITH bars AS (
  INSERT INTO bar (name) VALUES ('bar') RETURNING id
)
INSERT INTO foo (name, data) VALUES ('foo', jsonb_build_object('barId', (SELECT id FROM bars)));
  

Затем я могу создать функцию для отношения:

 CREATE FUNCTION foo_bar(foo_row foo)
RETURNS SETOF bar AS $$
  SELECT *
  FROM bar
  WHERE text(id) = foo_row.data ->> 'barId'
$$ LANGUAGE sql STABLE;
  

Затем я могу использовать это в Hasura в качестве вычисляемого поля в разделе «Данные» -> foo -> Изменить -> Вычисляемые поля -> «Добавить новое вычисляемое поле». Просто дайте ему имя и ссылайтесь на функцию в выпадающем списке:

введите описание изображения здесь

Затем я могу запросить:

 query MyQuery {
  foo {
    name
    foo_bar {
      name
    }
  }
}
  

с ожидаемым результатом:

 {
  "data": {
    "foo": [
      {
        "name": "foo",
        "foo_bar": [
          {
            "name": "bar"
          }
        ]
      }
    ]
  }
}