通过 GraphQL 键检索 AWS Amplify DataStore 记录

Posted

技术标签:

【中文标题】通过 GraphQL 键检索 AWS Amplify DataStore 记录【英文标题】:Retrieving AWS Amplify DataStore record by GraphQL Key 【发布时间】:2020-10-26 06:48:31 【问题描述】:

我在 Expo / React Native 中使用 AWS Amplify Datastore 来使用 GraphQL 存储配置文件信息。

架构如下所示:

type User @model  
  id: ID!
  username: String
  userPhone: String
  createdAt: String
  updatedAt: String

将其保存到数据存储区...

let input = 
    id: id,
    username: username,
    userPhone: userPhone,
    createdAt: createdAt,

let myDataStore = await DataStore.save(new User(input));

一旦它被保存到数据存储区,它看起来像这样。

dataStore is   User 
  "_deleted": undefined,
  "_lastChangedAt": undefined,
  "_version": undefined,
  "id": "f86d3252-7b1d-44f6-b4cd-b8a7a3a88def",
  "input": Object 
    "createdAt": 1593774031,
    "id": "3722f35e-de54-45b2-b26e-676e2cc48160",
    "userPhone": "",
    "username": "One Two",
  ,

code examples 显示如何通过数据存储 ID 检索此记录

DataStore.query(User, c => c.id("eq", "f86d3252-7b1d-44f6-b4cd-b8a7a3a88def"));

但是我想通过用户 id 检索它(“id”:“3722f35e-de54-45b2-b26e-676e2cc48160”),因为用户 id 实际上是 CognitoUser 子的值随时可用。按数据存储 id 查询需要将数据存储 id 保存在 AsyncStorage、状态、上下文、redux 或其他更笨重的东西中。

这不起作用

DataStore.query(User, c => c.input.id("eq", "3722f35e-de54-45b2-b26e-676e2cc48160"));

这不起作用

DataStore.query(User, c => c.id.id("eq", "3722f35e-de54-45b2-b26e-676e2cc48160"));

我确信有一个简单的答案,但我已经在谷歌上搜索了好几天,无法弄清楚。

感谢您的帮助。

【问题讨论】:

【参考方案1】:

我只是将其添加为评论,但我的排名低于 50 的声誉要求我将其发布为答案,所以这里是:

我认为你做错了,因为“输入”是用户对象内的一个字段,而不是只为构造函数获取参数。我不知道问题是什么,但我希望你不能自己设置“id”字段,无论如何。所以至少从输入中删除“id”字段。

尝试使用 DataStore.save() 命令来保存数据中没有此“输入”字段的用户。改为使用值更新/初始化用户成员字段。那么这应该工作:

DataStore.query(User, c => c.id("eq", "3722f35e-de54-45b2-b26e-676e2cc48160"));

如原始文档中所述。

P.S.:也许内联“输入”变量,所以试试这个:

let myDataStore = await DataStore.save(new User(
  username: "...",
  userPhone: "..."
));

【讨论】:

感谢您的回复,但我认为您不了解 Datastore 的工作原理。我的 dynomodb 表有 id、username 等字段,所以在 graphql 中输入 User @model id: ID! username: String userPhone: String createdAt: String updatedAt: String 当您使用 AWS Amplify DataStore 保存它时,它会添加自己的 id 字段,因为 dynamodb 中的 Datastore 表看起来像 id、dts 等等。 所以让我们换个方式玩吧,因为 id 会绊倒你。假设我想按用户名提取记录。如何查询数据存储区。当它看起来像 ser "_deleted": undefined, "_lastChangedAt": undefined, "_version": undefined, "id": "f86d3252-7b1d-44f6-b4cd-b8a7a3a88def", "input": Object "createdAt": 1593774031,“id”:“3722f35e-de54-45b2-b26e-676e2cc48160”,“userPhone”:“”,“用户名”:“一二”,,【参考方案2】:

添加到上一篇文章中,您可以在使用 id 检索单个项目时简化查询。您只需将 id 作为第二个参数传递。

const user = await DataStore.query(User, "f86d3252-7b1d-44f6-b4cd-b8a7a3a88def")

【讨论】:

【参考方案3】:

@Mat-KH 的回答实际上指向了正确的方向。 您的问题出在这一行(坦率地说,鉴于您的架构,这完全可行,我很惊讶):

let myDataStore = await DataStore.save(new User(input));

这会创建一个单独的 input 对象,从而导致您的数据嵌套在 User.input 中。

相反,你可以这样做

// create a new User
const input = 
    // id is auto-generated (see below)
    username: username,
    userPhone: userPhone,
    createdAt: createdAt,

const user = await DataStore.save(new User(input));

// the above auto-generates an ID -> use that in the query below
const user = await DataStore.query(User, c => c.id("eq", "f86d3252-7b1d-44f6-b4cd-b8a7a3a88def"));

【讨论】:

以上是关于通过 GraphQL 键检索 AWS Amplify DataStore 记录的主要内容,如果未能解决你的问题,请参考以下文章

通过 AWS AppSync GraphQL API 使用多种授权类型

通过 AWS AppSync 中的突变更新 GraphQL 数据时出错

如何通过 AWS AppSync 客户端将保存字符串的变量传递给 GraphQL 查询?

AppSync 和被锁定在 AWS 中的想法

AWS Amplify + Graphql + Dynamodb:突变时出现 ConditionalCheckFailedException 错误

我们可以在不使用 GraphQL 的情况下在项目中实施 AWS-Appsync 吗?