Как вы определяете upsert (если существует обновление, иначе вставьте) или даже обновление с помощью graphql?

Обновлено: я собираюсь дать здесь эквиваленты SQL, потому что это самый простой способ передать то, чему я пытаюсь найти эквивалент.

Схема для person

 id (system assigned clustered PK, probably a guid, doesnt really matter for this)
 FirstName : string
 LastName : string, required
 EmployeeCode : string, required, Unique

Я хочу иметь возможность представить такой запрос в GraphQL (BEGIN/END опущен для краткости), и только оператор UPDATE, и мне нужны примеры для любого из них, которые показывают, как нацеливаться на определенные записи, как это делает предложение WHERE.

IF EXISTS(SELECT TOP 1 1 FROM person WITH (UPDLOCK) WHERE EmployeeCode = 'ABC123')
   UPDATE person 
      SET FirstName = 'Mike'
          , LastName = 'Jones' 
   WHERE EmployeeCode = 'ABC123
ELSE
   INSERT person (FirstName, LastName, EmployeeCode) 
      VALUES ('Mike', "Hones', 'ABC123')

Спецификация GraphQl обсуждает мутации, но не то, как они выглядят. Примеры охватывают только сценарий INSERT. Единственное упоминание об обновлениях заключается в том, что они будут/должны/? выполняться последовательно.

Оригинальный вопрос -

Я хочу иметь возможность отправить один документ graphql, чтобы добавить запись, если ее не существует для указанных критериев, или обновить (частично или все неидентифицирующие/не PK/не NK поля) существующую, если указанные критерии соответствуют существующей записи .

Я могу сделать это несколькими способами на обычных диалектах SQL и в ElasticSearch (обновление по запросу). Но я не понимаю, как это должно быть указано или описано в graphql - и возможно ли это вообще.

В спецификации и в Интернете есть несколько примеров добавления записей, которые, по-видимому, требуют включения в документ вещей, которые выглядят так, будто они «дополнительные» или «приятные» (например, определения схемы/типа). Примеры обновлений часто имеют имена полей, аргументов и переменных, которые не совпадают (, например, Author.Id и authorId), или написаны с использованием языка, не относящегося к graphql, например Javascript (та же страница примера, что и «Автор».) эта двухэтапная операция от конечного клиента не кажется правильным подходом, так как только целевое хранилище данных будет знать, какая операция является правильной.

Не будет фиксированной предопределенной централизованной схемы для того, над чем я работаю, поскольку это многопользовательский API, и каждый арендатор может иметь разные определения для типа (например, у арендатора A есть объект контракта с 16 полями, но у арендатора B есть тип с тем же именем и предполагаемой функцией с полем 20. Оба будут использовать одно и то же пространство для хранения контрактов.

Возможно ли то, о чем я прошу? Если да, то можно ли поделиться примером?

никакие условия/сортировка/фильтрация и т. д. в запросе невозможны... зачем вы хотите это сделать? ... почему описания (в документах/спецификациях) поведения условной мутации (зависящего от переданного набора переменных) недостаточно ????????

xadm 17.12.2020 17:14

@xadm - я хочу этого, потому что я не хочу обновлять поле фамилии во всех записях о людях, чтобы оно было одинаковым, а только одним. Поскольку я нигде не могу найти связный пример, я спросил, может ли кто-нибудь здесь поделиться примером того, как будет выглядеть документ GraphQL для простого обновления, нацеленного на определенные записи (записи), и, если возможно, обновления для того же.

StingyJack 17.12.2020 17:49

Я написал, как это может работать .... Last сам по себе не проходит этап проверки в распознавателе (недостаточно аргументов для создания, нет аргумента ID для обновления) ... не влияет на все записи, никакие действия БД не выполняются, ошибка кинул, где сомнения? ... это не только запрос, это запрос + переменные + правила в распознавателе (и валидатор перед действием)

xadm 17.12.2020 17:58

@xadm - я ищу полный пример полезной нагрузки graphQL, отправляемой по сети от клиента на сервер либо для полного обновления, либо просто для обновления. Предоставление мне только кусочков этого не поможет, потому что я не знаю, как правильно собрать их, чтобы сделать запрос.

StingyJack 17.12.2020 18:27

просто попробовать построить PoC?

xadm 17.12.2020 18:40

@xadm - если я не могу составить синтаксис для обновления или обновления, как я могу продолжить создание PoC, демонстрирующего, как GraphQL может работать для того, что нам нужно?

StingyJack 17.12.2020 18:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Что такое Apollo Client и зачем он нужен?
Что такое Apollo Client и зачем он нужен?
Apollo Client - это полнофункциональный клиент GraphQL для JavaScript-приложений, который упрощает получение, управление и обновление данных в...
1
6
2 428
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

вставка-не-замена-обновления

...тогда это может быть вольная интерпретация...

createItem (назовите его upsertItem, если хотите) преобразователь мутаций может вставлять или обновлять (решение, связанное с BE, реализацией/хранилищем/БД) с или без строгих/явных определений типа ввода (требуется для создания, необязательно для обновления)

... арендаторы могут иметь разные типы ввода (количество полей) для одной и той же мутации

... в wp-graphql (WordPress) это даже основано на ролях - разные результаты самоанализа, разные аргументы для полей, разные доступные мутации... но это из динамического, непостоянного / без сохранения состояния php-символа

Вы можете просто ограничить использование полей (для каждого арендатора) или сопоставление типов (требуется/не требуется) в каком-либо «слое» проверки внутри преобразователя или в промежуточном программном обеспечении, просто выдавая ошибки (когда ввод не соответствует конкретному использованию/арендатору — например, return 'required ошибка» для некоторого поля, в то время как все поля в определениях типов являются необязательными). Когда запрос самоанализа заблокирован (в производстве), это просто проблема с документацией (не самоописание).

обновление - пример

если целевым объектом для обновления является человек с идентификатором, именем и фамилией (требуются идентификатор и фамилия)

ID здесь может не требоваться...

UpsertPersonInput со всеми (ID, First, Last) необязательными...

Для создания: upsertPerson( $input: UpsertPersonInput) {.. с переменными, необходимыми (по правилам проверки) для создания (First: "some", Last: "Name")

... ID здесь неизвестно, создано и возвращено как результат

... нет ID, тогда предполагается «режим создания»

Для обновления: запросите то же самое, но при наличии переменной input с проверкой ID prop работает в «режиме обновления» (требуется по крайней мере одна другая переменная — input prop — например, Last ... или другие дополнительные правила проверки)

... в то время как только input.ID поддержка предоставила > выдать какую-то ошибку «не требуется« Первый », переданный во входном аргументе» (любое поле) ... как это было бы в отдельной мутации обновления и ее типе ввода.

спасибо, если целевым объектом для обновления является человек с идентификатором, именем и фамилией (требуются идентификатор и фамилия), и обновление должно было исправить фамилию с ошибкой и поле для сопоставления с идентификатором, что на самом деле будет выглядеть graphql? Синтаксис этого - это то, где я борюсь.

StingyJack 16.12.2020 21:26

Извините, я имел в виду, что идентификатор и фамилия не могут быть нулевыми в сохраненной записи и должны были указать другое уникальное поле соответствия. На самом деле там будет системное поле «ID», которое мы можем пока игнорировать, а затем некоторые другие комбинированные поля, которые сделают запись уникальной в своей коллекции. В этом примере это может быть поле EmployeeCode. В этом случае это потребуется, поскольку оно не генерируется при нулевом значении и будет полем для сопоставления для определения обновления или вставки. Как на самом деле выглядит GraphQL для этой операции? Я ценю время, которое вы тратите, чтобы попытаться объяснить это

StingyJack 16.12.2020 22:17

нет никакой разницы, все же тип ввода содержит все возможные поля как необязательные... вам решать, как вы строите правила проверки для режимов создания и обновления (наличие какого подполя/реквизита определяет режим,... и для каждого из арендаторов - игнорировать или выдает при передаче неподдерживаемое свойство/подполе)

xadm 16.12.2020 22:34

Возможно, мне следует перефразировать проблему — у GraphQL нет какого-либо предложения WHERE, которое я мог бы использовать для идентификации записей, на которые нужно воздействовать. На самом деле я не думаю, что это правда, но я не могу найти пример мутации GraphQL, которая выполняет обновление это использование любого вида фильтрации предикатов.

StingyJack 17.12.2020 04:11

никакой сортировки/фильтрации/и т.д. в спецификациях ... не роль запроса, чтобы определить, как должен работать распознаватель ... он управляется данными ... вы МОЖЕТЕ интерпретировать (например, проверять режим) переменные, вы МОЖЕТЕ разрешать (работать в режиме создания или обновления) переменные. ... это деталь реализации ... вы определяете, что могут означать входные данные / аргументы ... предложение WHERE для работы над чем? БД/файл/удаленная служба/источник данных?

xadm 17.12.2020 07:02
UPDATE person SET LastName = 'Jones' WHERE EmployeeCode = 'ABC123' - это то, чему я пытаюсь найти эквивалент. Все, что я могу найти, это примеры для INSERT person (FirstName, LastName, EmployeeCode) VALUES ('Mike', "Hones', 'ABC123')
StingyJack 17.12.2020 16:23

если нет какой-либо поддержки, вы должны построить ее из входных данных в преобразователе (при необходимости) ... исследовали ли вы какой-либо API-интерфейс graphql с фильтрацией/сортировкой/условиями? тонны из них ... тем не менее, это скрывает детали реализации

xadm 17.12.2020 16:29
Ответ принят как подходящий

Ответ... нет. Нет никакого синтаксиса или грамматики для указания или выражения поведения обновления в GraphQL, кроме общей идеи преобразователя, для которого вам придется полностью создать свой собственный синтаксис. Для меня это означает неполный язык запросов.

Почему этот разрыв продолжает существовать, в настоящее время я не понимаю, но для целей этого вопроса ответ будет разочаровывающим «Нет», когда дело доходит до обновления.

Яблоки с апельсинами... сравните с REST... нет синтаксиса? наверное никогда не будет... собственный синтаксис? не совсем ... тип ввода для условий от многих поставщиков похож, древовидная структура where (проведите некоторое исследование) ... да, это не стандартизировано (в спецификациях) СЕЙЧАС, но это не останавливает людей ... но это зависит от вам, что это where означает в вашем API... удивительно, что они создают похожие решения, адаптированные к среде/методологии и ее возможностям (не придерживаясь старых, хорошо известных решений)... к сожалению, вы этого не чувствуете/не чувствуете не вижу силы в этой свободе...плохо для вас, а не для графа

xadm 21.12.2020 16:06

@xadm - я очень ценю, что вы придерживаетесь этого, и должен вам хотя бы одно пиво. Я только пытаюсь сравнить это с другими языками/функциями запросов объектов или данных/типов (также известных как графики), и именно здесь я нахожу это недостаточным. Если вы действительно думаете, что это не так, поделитесь полным примером полезной нагрузки graphql, которая потребуется для отправки на сервер, который удовлетворяет как минимум обновлению фамилии для существующей записи человека на основе сопоставления по коду сотрудника (как указано в ОП), без использования какого-либо пользовательского синтаксиса.

StingyJack 21.12.2020 20:01

Нет никакой свободы, когда вы должны указать все поля в обновлении, иначе они будут установлены в NULL при использовании GraphQL. Нет никакой свободы, когда у вас есть таблица, такая как ниже: ТАБЛИЦА 1 (ID NUMBER PK NOT NULL, FIRSTNAME VARCHAR2 (20), LASTNAME VARCHAR2 (20), COMPANY VARCHAR2 (25), STATUS VARCHAR2 (10))

и в Oracle или любой другой базе данных я мог бы легко обновить статус всех записей, соответствующих условиям ОБНОВЛЕНИЕ ТАБЛИЦЫ 1 УСТАНОВИТЬ СТАТУС = 'ГОТОВО' ГДЕ КОМПАНИЯ = 'XYZ CORP';

но в GraphQL я должен указать идентификатор в обновлении или получить сообщение об ошибке «Требуется идентификатор ...» или включить все столбцы в таблицу Это очень неэффективно.

Другие вопросы по теме