Отношение "один ко многим" не отображается в определении схемы Amplify.

Я новичок в использовании расширения с GraphQL. Я настраивал свою схему БД и автоматически генерировал функции после запуска ampify push.

Цели, которых я хочу достичь, но не знаю как

  1. Я хотел бы иметь возможность получить пользователя со всей связанной информацией (с отношениями один к одному и один ко многим) в возвращаемом объекте из getUser
  2. Я бы хотел по-прежнему получать 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, а также дать мне возможность получить пользователь по имени пользователя. Любой вклад будет оценен!!!

2 ответа

Это проблема с глубиной запроса. это 2по умолчанию и нужно увеличить его (до в вашем случае).

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

  1. Бежать amplify codegen configure- Это снова подскажет конфиги.
  2. Войти 4для этого варианта Enter maximum statement depth [increase from default if your schema is deeply nested]
  3. Бежать amplify codegen- это создаст ваши запросы и мутации в соответствии с новой глубиной.

Вы можете убедиться в этом, проверив .

Ранее вы могли видеть ниже фрагмент в getUserзапрос в grapgql/queries.js,

      buttons {
  nextToken
}

Но после выполнения вышеуказанных шагов разрешения это должно быть примерно так, как показано ниже.

      buttons {
    items {
        id
        image
        address
      }
  }

Наконец, снова запросите вашего пользователя.

Общий комментарий: если имя пользователя уникально, вы можете использовать его как идентификатор вместо создания дополнительного индекса. В противном случае с этой схемой возникнут проблемы, поскольку она не может выполнить getOperation, а вместо этого выполнит запрос, который может вернуть несколько ответов.

(Решатель в Appsync хочет использовать dynamoDB.get по умолчанию (& дизайн), но использование индекса будет dynamoDB.query что приводит к множеству проблем)

В любом случае, используя вашу схему, я могу заставить ее работать нормально при использовании идентификатора

  "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
      }
    }
  }
}

Вот тот, где я сделал адрес электронной почты идентификатором.

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!
}

Может я что-то не понял?

Другие вопросы по тегам