对象 Amplify Schema 定义中未显示一对多关系

Posted

技术标签:

【中文标题】对象 Amplify Schema 定义中未显示一对多关系【英文标题】:One to Many Relationship not showing in the object Amplify Schema definition 【发布时间】:2020-12-22 06:01:30 【问题描述】:

我不熟悉将 amplify 与 GraphQL 一起使用。我正在设置我的数据库架构并在运行放大推送后自动生成函数。

我想实现但不知道如何实现的目标

    我希望能够在从 getUser 返回的对象中获取具有所有关联信息(具有一对一和一对多关系)的用户 我希望仍然能够获取 userByUserName 并查看所有连接的一对多关系

调用API生成函数获取用户时,

let user = await API.graphql(graphqlOperation(getUser,id:userId))

我正在取回一个用户对象,但是,它看起来像这样 - 尽管我确信数据库中的数据设置正确。

buttons: nextToken: null -- WANT THIS TO INCLUDE ACTUAL INFORMATION ABOUT BUTTONS CONNECTED TO THIS USER
createdAt: "2020-09-02T23:41:12.278Z"
customStyles: id: "e3d1bbef-ec6f-4a6d-9b5d-e693e890d4e0", bgColor: "F9FF9F", bgBtnColor: "FFFFFF", bgBtnHoverColor: "000000", textColor: "000000", …
defaultStyles: null
email: "nata@email.edu"
firstName: "Nata"
id: "d683a6bb-383e-4cf1-943a-05b3da4e5cc3"
lastName: "Vache"
socialNetwork: nextToken: null -- WANT THIS TO INCLUDE ACTUAL INFORMATION ABOUT SOCIAL NETWORKS CONNECTED TO THIS USER, THE SAME WAY AS FOR EXAMPLE customStyles IS SHOWN. 
updatedAt: "2020-09-02T23:41:12.278Z"
userName: "Nata568"

type User @model @key(name: "byUserName", fields: ["userName"], queryField: "userByUserName")
  id: ID!
  firstName: String!
  lastName: String!
  userName: String!
  email: String!
  socialNetwork: [UserSocialNetwork] @connection(keyName: "UserSocialNetworkUser", fields: ["id"])
  buttons: [Button] @connection(keyName: "ButtonUser", fields: ["id"])
  defaultStyles: DefaultStyle @connection
  customStyles: CustomStyle @connection


type UserSocialNetwork @model @key(name: "UserSocialNetworkUser", fields: ["userID", "id"], queryField:"userSocialNetworkByUserID") 
  id: ID!
  socialNetworkUsername: String!
  userID: ID!
  supportedSocialNetwork: SupportedSocialNetwork! @connection


type SupportedSocialNetwork @model 
  id: ID!
  name: String!
  address: String!


type Button @model @key(name: "ButtonUser", fields: ["userID", "id"], queryField: "buttonByUserID") 
  id: ID!
  name: String!
  address: String!
  image: String
  userID: ID!

此架构不包括我的所有模型定义 - customStyles、defaultStyles 和其他,但它们是一对一的关系,运行良好。我遇到了一对多关系的问题,例如用户到 UserSocialNetwork 和用户到按钮。

我在 AWS Amplify Docs 上阅读了很多关于这方面的资源,浏览了一些示例,但仍然没有找到任何可以让我从 getUser 调用的连接中获取信息并赋予我能力的东西通过用户名获取用户。 任何意见将不胜感激!!!

【问题讨论】:

如果这能解释您的问题的解决方案,您能否接受我的回答:) 【参考方案1】:

这是查询深度的问题。默认为2,需要增加它(在你的情况下为4)。

您可以按照以下步骤解决此问题。 在项目根目录下的 cmd 中(通常在其中运行放大命令)。

    运行amplify codegen configure - 这将再次提示配置。 为此选项输入4 Enter maximum statement depth [increase from default if your schema is deeply nested] 运行amplify codegen - 这将根据新的深度创建您的查询和突变。

您可以通过检查grapgql/queries.js来验证它。

之前你可以在grapgql/queries.jsgetUser 查询中看到下面的片段,

buttons 
  nextToken

但是按照上述解决步骤后,它应该类似于下面。

buttons 
    items 
        id
        image
        address
      
  

最后再次查询你的用户。

【讨论】:

【参考方案2】:

一般评论:如果用户名是唯一的,您可以使用它作为 id 而不是创建额外的索引。如果不是,则此架构将出现问题,因为它无法执行 getOperation 而是执行可能返回多个答案的查询。

(Appsync 中的解析器希望默认使用dynamoDB.get(设计),但使用索引将是dynamoDB.query,这会导致很多问题)

无论如何使用您的架构我可以让它在使用 id 时正常工作

  "data": 
    "getUser": 
      "createdAt": "2020-09-07T13:54:23.440Z",
      "email": "meax",
      "firstName": "Max",
      "id": "19a752ec-5050-4e02-8ff8-05d9523e7ea5",
      "socialNetwork": 
        "items": [
          
            "socialNetworkUsername": "What",
            "id": "280ec8ea-5b25-46d3-8f22-f170e3210146",
            "userID": "19a752ec-5050-4e02-8ff8-05d9523e7ea5"
          
        ]
      ,
      "lastName": "Sc",
      "userName": "zanndo",
      "updatedAt": "2020-09-07T13:54:23.440Z",
      "buttons": 
        "items": [
          
            "id": "65971568-b388-40a3-b99e-1bff0a730161",
            "image": null,
            "address": "ButonAdre"
          
        ]
      
    
  

这是我的问题

getUser(id: "19a752ec-5050-4e02-8ff8-05d9523e7ea5") 
    createdAt
    email
    firstName
    id
    socialNetwork 
      items 
        socialNetworkUsername
        id
        userID
      
    
    lastName
    userName
    updatedAt
    buttons 
      items 
        id
        image
        address
      
    
  

这是我在电子邮件中设置 id 的地方。

query MyQuery 
  getUser(id: "sw@gmail.com") 
    id
    firstName
    lastName
    socialNetwork 
      items 
        socialNetworkUsername
        supportedSocialNetwork 
          name
          id
          address
        
      
    
    buttons 
      items 
        id
        address
        name
      
    
  

同样有效


  "data": 
    "getUser": 
      "id": "sw@gmail.com",
      "firstName": "S",
      "lastName": "W",
      "socialNetwork": 
        "items": [
          
            "socialNetworkUsername": "SomeUserNameOrSomething",
            "supportedSocialNetwork": 
              "name": "Supported1",
              "id": "daf52246-4b25-402c-9fdd-46f8f35e1b89",
              "address": "SupportedAddr"
            
          
        ]
      ,
      "buttons": 
        "items": [
          
            "id": "9883bd91-a2f1-479d-ab65-7a4bbe7b2dc4",
            "address": "ButtonAddr",
            "name": "Button1"
          
        ]
      
    
  

使用您的索引获得奖励

  userByUserName(userName: "SW") 
    items 
      buttons 
        items 
          name
          id
        
      
      socialNetwork 
        items 
          socialNetworkUsername
          supportedSocialNetwork 
            name
          
        
      
    
  
"userByUserName": 
      "items": [
        
          "buttons": 
            "items": [
              
                "name": "Button1",
                "id": "9883bd91-a2f1-479d-ab65-7a4bbe7b2dc4"
              
            ]
          ,
          "socialNetwork": 
            "items": [
              
                "socialNetworkUsername": "SomeUserNameOrSomething",
                "supportedSocialNetwork": 
                  "name": "Supported1"
                
              
            ]
          
        
      ]
    

这是我使用的架构

type User @model @key(name: "byUserName", fields: ["userName"], queryField: "userByUserName")
  firstName: String!
  lastName: String!
  userName: String!
  id: String!
  socialNetwork: [UserSocialNetwork] @connection(keyName: "UserSocialNetworkUser", fields: ["id"])
  buttons: [Button] @connection(keyName: "ButtonUser", fields: ["id"])


type UserSocialNetwork @model @key(name: "UserSocialNetworkUser", fields: ["userID", "id"], queryField:"userSocialNetworkByUserID") 
  id: ID!
  socialNetworkUsername: String!
  userID: String!
  supportedSocialNetwork: SupportedSocialNetwork! @connection


type SupportedSocialNetwork @model 
  id: ID!
  name: String!
  address: String!


type Button @model @key(name: "ButtonUser", fields: ["userID", "id"], queryField: "buttonByUserID") 
  id: ID!
  name: String!
  address: String!
  image: String
  userID: String!

也许我误解了什么?

【讨论】:

您的回答是否表明我们需要使用自定义查询来解决此问题?我更多地认为我们可以使用放大生成的函数 getUser 和 userByUserName。当我查看您的架构时,我没有看到太多变化,我假设最初那里有一些错误。您提供的对象数据是我希望在 getUser 和 userByUserName 上看到的,但不确定您是否通过创建自定义查询来实现。 不,我只是用你的模式运行了很多,还是“自定义查询”指的是 GraphQL 查询? Amplify 的自动生成远非完美(尤其是在某些连接中)。您可能想检查您的数据库是否对我的查询给出了正确的答案。如果是这样,您可以检查您的“深度级别”是否不够深,无法让 Amplify 创建正确的查询。也许您的自动生成的查询是错误的(很容易发生)?你检查过吗?

以上是关于对象 Amplify Schema 定义中未显示一对多关系的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 Amplify 的 schema.graphql 中指定 2 个带有身份验证注释的 Cognito 用户池?

如何在自定义解析器 AWS Amplify CLI 中查询 API?

来自商店的数据中未定义的数组中的 Vue.js 对象

其他对象中未显示的对象属性

回收站视图项目中未显示分隔线

为啥在第一次组件渲染中未定义 useState 对象值?