通过 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 记录的主要内容,如果未能解决你的问题,请参考以下文章