您如何使用 graphql 定义更新插入(如果存在则更新否则插入)甚至更新?
How do you define an upsert (if exists update else insert) or even an update using 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 spec discusses mutations but not what it looks like. The examples只涵盖INSERT场景。关于更新的唯一提及是它们 will/must/?连续执行。
原题-
我希望能够发送单个 graphql 文档来添加记录,如果 none 存在指定的条件,或更新(部分或全部非 ident/non PK/non NK字段)一个现有的,如果指定的条件匹配一个现有的记录。
我可以在传统的 SQL 方言和 ElasticSearch(通过查询更新)中使用几种方法来做到这一点。但我看不到它应该如何在 graphql 中指定或描述 - 或者如果它可能的话。
在规范和网络上有一些添加记录的示例,这些示例似乎需要看起来像 (like schema/type definitions) to be included in the document. The update examples often have field, argument, and variable names that dont match (like Author.Id and authorId) 的东西,或者是使用非 graphql 特定语言编写的,例如 Javascript(与“作者”相同的示例页面。)从终端客户端执行这两个阶段的操作似乎也不是正确的方法,因为只有目标数据存储才会知道哪个是正确的操作。
作为多租户,我正在处理的工作不会有固定的预定义集中模式 API,并且每个租户可能对一种类型有不同的定义(例如,租户 A 有一个合同具有 16 个字段的实体,但租户 B 具有具有 20 个字段的相同名称和预期功能的类型。两者将共享相同的存储空间 space 用于合同。
我问的有没有可能?如果可以,可以分享一个例子吗?
upsert-is-not-a-substitute-for-update
...那么它可以是一个宽松的解释...
createItem
(如果你愿意,可以命名为upsertItem
)突变解析器可以插入或更新(BE,解析器implementation/storage/DB相关决定)有或没有 strict/explicit 输入类型定义(创建需要,更新可选)
...对于同一个突变,租户可以有不同的输入类型(字段数量)
...在 wp-graphql(WordPress)中它甚至是基于角色的 - 不同的内省结果,不同的字段参数,不同的可用突变......但它来自动态,non-persistent/stateless php字符
您可以限制字段使用(每个租户)或类型匹配(required/not 需要)在某些 验证 'layer' 内部解析器或中间件 中通过抛出错误(当输入与某些字段的特定 usage/tenant - f.e. return 'required error' 不匹配时,而类型定义中的所有字段都是可选的)。当内省查询被阻止(在生产中)时,这只是一个文档问题(不是自我描述)。
更新-示例
if the target entity to upsert is a Person with an ID, and First, and Last names, (ID and Last are required)
ID
这里不能要求...
UpsertPersonInput
所有 (ID
, First
, Last
) 可选 ...
对于创建:upsertPerson( $input: UpsertPersonInput) {..
具有创建所需的变量(通过验证规则)(First: "some", Last: "Name"
)
...ID
此处未知,已创建并 returned 作为结果
...没有提供 ID
然后假设 'creation mode'
对于更新:查询相同但当提供 input
变量和 ID
prop 验证在 'update mode' 中工作(至少另一个变量 - input
prop - 必需,f.e。Last
... 或其他附加验证规则)
... 虽然只提供了 input.ID
道具 > 抛出一些“不需要 'First' 在输入参数中传递”(任何字段)错误...因为它会在单独的更新突变及其输入类型。
答案是……你不知道。在 GraphQL 中没有用于指定或表达更新行为的句法或文法,除了解析器的笼统概念,您将必须完全创建自己的句法。对我来说,解析为不完整的查询语言。
为什么这个差距继续存在目前我无法理解,但就这个问题而言,在更新方面,答案是令人失望的“否”。
当您必须在更新中提供所有字段时,没有自由,否则在使用 GraphQL 时将它们设置为 NULL。当你有一个 table 时,就没有自由,如下所示:
TABLE1 ( ID NUMBER PK NOT NULL, FIRSTNAME VARCHAR2(20), LASTNAME VARCHAR2(20), COMPANY VARCHAR2(25), STATUS VARCHAR2(10) )
并且在 Oracle 或任何其他数据库中,我可以轻松地更新满足条件的所有记录的状态
更新表 1
设置状态 = 'DONE'
公司所在地 = 'XYZ CORP';
但在 GraphQL 中,我必须在更新中提供 ID 或收到错误“需要 ID...”或必须包含 table 中的所有列
那是非常低效的。
编辑:我将在这里给出 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 spec discusses mutations but not what it looks like. The examples只涵盖INSERT场景。关于更新的唯一提及是它们 will/must/?连续执行。
原题-
我希望能够发送单个 graphql 文档来添加记录,如果 none 存在指定的条件,或更新(部分或全部非 ident/non PK/non NK字段)一个现有的,如果指定的条件匹配一个现有的记录。
我可以在传统的 SQL 方言和 ElasticSearch(通过查询更新)中使用几种方法来做到这一点。但我看不到它应该如何在 graphql 中指定或描述 - 或者如果它可能的话。
在规范和网络上有一些添加记录的示例,这些示例似乎需要看起来像
作为多租户,我正在处理的工作不会有固定的预定义集中模式 API,并且每个租户可能对一种类型有不同的定义(例如,租户 A 有一个合同具有 16 个字段的实体,但租户 B 具有具有 20 个字段的相同名称和预期功能的类型。两者将共享相同的存储空间 space 用于合同。
我问的有没有可能?如果可以,可以分享一个例子吗?
upsert-is-not-a-substitute-for-update
...那么它可以是一个宽松的解释...
createItem
(如果你愿意,可以命名为upsertItem
)突变解析器可以插入或更新(BE,解析器implementation/storage/DB相关决定)有或没有 strict/explicit 输入类型定义(创建需要,更新可选)
...对于同一个突变,租户可以有不同的输入类型(字段数量)
...在 wp-graphql(WordPress)中它甚至是基于角色的 - 不同的内省结果,不同的字段参数,不同的可用突变......但它来自动态,non-persistent/stateless php字符
您可以限制字段使用(每个租户)或类型匹配(required/not 需要)在某些 验证 'layer' 内部解析器或中间件 中通过抛出错误(当输入与某些字段的特定 usage/tenant - f.e. return 'required error' 不匹配时,而类型定义中的所有字段都是可选的)。当内省查询被阻止(在生产中)时,这只是一个文档问题(不是自我描述)。
更新-示例
if the target entity to upsert is a Person with an ID, and First, and Last names, (ID and Last are required)
ID
这里不能要求...
UpsertPersonInput
所有 (ID
, First
, Last
) 可选 ...
对于创建:upsertPerson( $input: UpsertPersonInput) {..
具有创建所需的变量(通过验证规则)(First: "some", Last: "Name"
)
...ID
此处未知,已创建并 returned 作为结果
...没有提供 ID
然后假设 'creation mode'
对于更新:查询相同但当提供 input
变量和 ID
prop 验证在 'update mode' 中工作(至少另一个变量 - input
prop - 必需,f.e。Last
... 或其他附加验证规则)
... 虽然只提供了 input.ID
道具 > 抛出一些“不需要 'First' 在输入参数中传递”(任何字段)错误...因为它会在单独的更新突变及其输入类型。
答案是……你不知道。在 GraphQL 中没有用于指定或表达更新行为的句法或文法,除了解析器的笼统概念,您将必须完全创建自己的句法。对我来说,解析为不完整的查询语言。
为什么这个差距继续存在目前我无法理解,但就这个问题而言,在更新方面,答案是令人失望的“否”。
当您必须在更新中提供所有字段时,没有自由,否则在使用 GraphQL 时将它们设置为 NULL。当你有一个 table 时,就没有自由,如下所示: TABLE1 ( ID NUMBER PK NOT NULL, FIRSTNAME VARCHAR2(20), LASTNAME VARCHAR2(20), COMPANY VARCHAR2(25), STATUS VARCHAR2(10) )
并且在 Oracle 或任何其他数据库中,我可以轻松地更新满足条件的所有记录的状态 更新表 1 设置状态 = 'DONE' 公司所在地 = 'XYZ CORP';
但在 GraphQL 中,我必须在更新中提供 ID 或收到错误“需要 ID...”或必须包含 table 中的所有列 那是非常低效的。