Как сделать данные в разных таблицах DynamoDB реляционными? - PullRequest
1 голос
/ 07 августа 2020

В настоящее время я слежу за документами AWS Amplify и использую схему 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 Ответ

1 голос
/ 07 августа 2020

Вам следует сохранить каждую из ваших моделей, если вы этого не сделали, например, я вижу, вы создали блог, а затем сообщение с блогом. Вам нужно будет сохранить блог, а затем сохранить сообщение, иначе блог не существует в DynamoDB. Это выглядит правильно для сообщения и комментария, поскольку вы сохраняете сообщение, а затем комментарий (содержащий сообщение для ассоциации).

Данные сохраняются, но не возвращаются вашему клиенту. В настоящее время построитель, который используется для создания GraphQLRequest .list(Post.self, where: predicate), будет генерировать только набор выбора для возврата сообщения, но не дополнительный список связанных комментариев. По умолчанию это глубина обхода 1. В настоящее время Amplify для Android делает это по-другому, и в репозитории есть существующая проблема, чтобы отслеживать, следует ли обновить ее, чтобы по умолчанию глубина обхода была равна 2. https://github.com/aws-amplify/amplify-ios/issues/681

Один из способов обхода здесь - создать свой собственный запрос GraphQL с набором выбора, который содержит как сообщение, так и комментарии. Или настраиваемый запрос GraphQL для запроса списка, который имеет параметр фильтра, который вы установили для фильтрации для определенного идентификатора сообщения.

Вы можете увидеть, что этот пример здесь создает вложенный набор выбора с сообщением и комментариями: 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 https://github.com/aws-amplify/amplify-ios/issues, поскольку это поможет нам облегчить разговор

...