如何使不同 DynamoDB 表中的数据相互关联?

Posted

技术标签:

【中文标题】如何使不同 DynamoDB 表中的数据相互关联?【英文标题】:How to make data in different DynamoDB Tables relational? 【发布时间】:2020-11-27 04:41:48 【问题描述】:

我目前正在关注AWS Amplify docs,并且我正在使用默认博客 GraphQL 架构来尝试创建关系 Dynamo DB 表。

博客模型表显示在 DynamoDB 中,我可以向它们上传信息,但我不知道如何使它们具有关系。模型类型为 BlogPostComment 。例如,在将帖子上传到其 DynamoDB 表后,如何将上传的评论链接到同一个帖子?在我的 Swift 代码中,我尝试这样做但无济于事。

我也不理解List<Comment>.init() 的语法,它可能不应该存在,但没有给出错误。也许这就是我的问题的原因。

创建帖子:

     let blog = Blog(name: "UserBlog", posts: List<Post>.init())
        let posts = Post(title: "Testing out AWS", blog:blog, comments: List<Comment>.init())
        _ = Amplify.API.mutate(request: .create(posts))  event in
            switch event 
            case .success(let result):
                switch result 
                case .success(let post):
                        print("Successfully created the post: \(post)")
                case .failure(let graphQLError):
                    print("Failed to create graphql \(graphQLError)")
                
            case .failure(let apiError):
                print("Failed to create a todo", apiError)
           
            
        

调试控制台的输出

Successfully created the post: Post(id: "83D71F16-6B0D-453A-A163-AABF484CE527", title: "Testing out AWS", blog: nil, comments: nil)

然后在使用此代码为该帖子创建评论后

  let blog = Blog(name: "UserBlog", posts: List<Post>.init())
        let posts = Post(title: "Testing out AWS", blog:blog, comments: List<Comment>.init())
        let comments = Comment(content: "It worked", post: posts)
        _ = Amplify.API.mutate(request: .create(comments))  event in
            switch event 
            case .success(let result):
                switch result 
                case .success(let comment):
                        print("Successfully created the comment: \(comment)")
                case .failure(let graphQLError):
                    print("Failed to create graphql \(graphQLError)")
                
            case .failure(let apiError):
                print("Failed to create a todo", apiError)
           
            
        

调试控制台的输出

Successfully created the comment: Comment(id: "85395F8B-C8C2-4ACB-8FC5-DAEFC2728C32", content: Optional("It worked"), post: nil)

最后在使用此代码从表中获取之后

        let post = Post.keys
           let predicate = post.title == "Testing out AWS"
           _ = Amplify.API.query(request: .list(Post.self, where: predicate))  event in
               switch event 
               case .success(let result):
                   switch result 
                   case .success(let post):
                       print("Successfully retrieved list of posts: \(post)")

                   case .failure(let error):
                       print("Got failed result with \(error.errorDescription)")
                   
               case .failure(let error):
                   print("Got failed event with error \(error)")
               
           

调试控制台的输出

Successfully retrieved list of posts: [testAWS.Post(id: "83D71F16-6B0D-453A-A163-AABF484CE527", title: "Testing out AWS", blog: nil, comments: nil)]

如何将评论链接到帖子,以便在查询时显示评论而不是nil

我的架构:

type Blog @model 
  id: ID!
  name: String!
  posts: [Post] @connection(name: "BlogPosts")

type Post @model 
  id: ID!
  title: String!
  blog: Blog @connection(name: "BlogPosts")
  comments: [Comment] @connection(name: "PostComments")

type Comment @model 
  id: ID!
  content: String
  post: Post @connection(name: "PostComments")

【问题讨论】:

【参考方案1】:

如果您还没有保存每个模型,则应该保存它,例如,我看到您创建了一个博客,然后在该博客上发表了一篇文章。您需要保存博客,然后保存帖子,否则 DynamoDB 中不存在该博客。帖子和评论看起来是正确的,因为您先保存帖子,然后再保存评论(包含关联帖子)。

数据已保留,但不会返回给您的客户。目前,用于创建 GraphQLRequest .list(Post.self, where: predicate) 的构建器将仅生成选择集以返回 Post,但不会生成连接 cmets 的可选列表。默认情况下,步行深度为 1。目前,Amplify for android 以不同方式执行此操作,并且在存储库中打开了一个现有问题,以跟踪是否应将其更新为默认步行深度为 2。 https://github.com/aws-amplify/amplify-ios/issues/681

这里的一种解决方法是使用包含帖子和 cmets 的选择集创建您自己的自定义 GraphQL 请求。或者针对列表查询的自定义 GraphQL 请求,该请求具有您设置为过滤特定 post.id 的过滤器参数。

您可以在此处看到此示例创建了一个包含 post 和 cmets 的嵌套选择集:https://github.com/aws-amplify/docs/blob/fbe1773bd21476954f379909b7a9a7abf3f02c2a/docs/lib/graphqlapi/fragments/ios/advanced-workflows.md#nested-data

extension GraphQLRequest 
    static func getPostWithComments(byId id: String) -> GraphQLRequest<JSONValue> 
        let document = """
        query getPost($id: ID!) 
          getPost(id: $id) 
            id
            title
            rating
            status
            comments 
              items 
                id
                postID
                content
              
            
          
        
        """
        return GraphQLRequest<JSONValue>(document: document,
                                         variables: ["id": id],
                                         responseType: JSONValue.self)
    

请随时在 github repo https://github.com/aws-amplify/amplify-ios/issues 中发布您的问题,因为这将有助于我们促进对话

【讨论】:

以上是关于如何使不同 DynamoDB 表中的数据相互关联?的主要内容,如果未能解决你的问题,请参考以下文章

DynamoDB 流 和 AWS Lambda 触发器

如何按日期(范围键)查询 DynamoDB,没有明显的哈希键?

检索DynamoDB表中的所有数据并随后清除表的最佳方法

在 phpmyadmin 中,我如何将单个数据库中两个不同表中的两个特定行相互链接并保持自动化?

【Tableau】Tableau中的数据关联(联接)

将 spark 数据帧行写入 dynamoDB 表中的项目