如何使不同 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 中,我可以向它们上传信息,但我不知道如何使它们具有关系。模型类型为 Blog
、 Post
和 Comment
。例如,在将帖子上传到其 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,没有明显的哈希键?