You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Amplify创建Items关联ItemCategory报错的解决咨询

创建关联分类的Item时GraphQL输入字段报错解决方法

问题背景

我的schema.graphql定义如下:

type Items @model {
  id: ID!
  ItemName: String!
  ItemDescription: String
  ItemCategory: Categories
  ItemEvents: [Events]
  ItemAttributes: [Attributes]
  createdAt: AWSDateTime
  updatedAt:AWSDateTime
}

type Categories @model {
  id: ID!
  CategoryName: String!
  CategoryItems: [Items]
  createdAt: AWSDateTime
  updatedAt:AWSDateTime
}

AWS Amplify自动生成的mutation.js内容:

export const createItems = /* GraphQL */ `
  mutation CreateItems(
    $input: CreateItemsInput!
    $condition: ModelItemsConditionInput
  ) {
    createItems(input: $input, condition: $condition) {
      id
      ItemName
      ItemDescription
      ItemCategory {
        id
        CategoryName
        CategoryItems {
          id
          ItemName
          ItemDescription
          createdAt
          updatedAt
        }
        createdAt
        updatedAt
      }
      createdAt
      updatedAt
    }
  }
`;

前端App.js中通过表单创建Item的代码:

{
  Categories.map(Category => ( // 遍历分类列表
    <form onSubmit={(e) => createItemInput(e, Category)}>
      <div className='item_input'>
        <input type="text" name="itemName" placeholder="New Item"/>
      </div>

      <button type="submit" id = "newItemButton">
        <svg width="30" height="30" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg">
          <line x1='0' y1='60' x2='120' y2='60' stroke='black' />
          <line x1='60' y1='0' x2='60' y2='120' stroke='black' />
        </svg>
      </button>
    </form>
  ))
}

相关状态和函数:

const initialFormState = { ItemName: "", ItemDescription: "", ItemCategory: {}}; // 表单输入初始状态

const [Items, setItems] = useState([]); // Item数组
const [formData, setFormData] = useState(initialFormState); // 表单数据

async function createItem() { // 创建Item的函数
  if (!formData.ItemName) return;

  await API.graphql({
    query: mutations.createItems,
    variables: {
      input: formData
    }
  })
}

function createItemInput(e, currentCategory) {
  e.preventDefault();
  var iname = e.target.itemName.value;
  setFormData({ ...formData, 'ItemName': iname, 'ItemCategory': currentCategory});
  createItem();
}

问题现象

点击创建按钮时出现错误:"The variables input contains a field name 'ItemCategory' that is not defined for input object type 'CreateItemsInput'"。虽然mutation返回字段包含ItemCategory,但调用时无法传入关联的Category对象。直接在DynamoDB手动创建带ItemCategory映射的Item可行,但代码调用不被接受。移除ItemCategory相关代码后可正常创建Item,但需要保留分类关联功能。

尝试过的操作

手动在GraphQL中添加输入类型定义:

input CreateItemsInput {
  ItemName: String!
  ItemDescription: String
  ItemCategory: Categories
}

执行amplify push时更新失败,移除ItemCategory: Categories后推送成功,但无法实现关联需求。

解决方案

1. 修正GraphQL Schema,使用@connection定义关联

Amplify需要通过@connection指令明确建立模型间的关联关系,自动生成正确的输入类型和外键字段。修改后的schema如下:

type Items @model {
  id: ID!
  ItemName: String!
  ItemDescription: String
  ItemCategory: Categories @connection(fields: ["categoryId"])
  categoryId: ID # 新增外键字段,用于关联Categories的id
  ItemEvents: [Events]
  ItemAttributes: [Attributes]
  createdAt: AWSDateTime
  updatedAt:AWSDateTime
}

type Categories @model {
  id: ID!
  CategoryName: String!
  CategoryItems: [Items] @connection(keyName: "byCategory", fields: ["id"])
  createdAt: AWSDateTime
  updatedAt:AWSDateTime
}
  • @connection(fields: ["categoryId"]) 指定Items通过categoryId字段关联到Categories
  • Categories中的@connection(keyName: "byCategory", fields: ["id"]) 建立反向关联,方便通过分类查询所属Item

2. 更新前端代码,传入外键而非完整Category对象

Amplify生成的CreateItemsInput会包含categoryId字段,而非直接接受Category对象。修改前端状态和函数:

// 调整初始表单状态
const initialFormState = { ItemName: "", ItemDescription: "", categoryId: "" };

// 修改创建Item的输入处理函数
function createItemInput(e, currentCategory) {
  e.preventDefault();
  var iname = e.target.itemName.value;
  // 传入分类的id到categoryId字段,而非完整对象
  setFormData({ ...formData, ItemName: iname, categoryId: currentCategory.id });
  createItem();
}

3. 重新生成Amplify资源

执行amplify push,Amplify会根据修正后的schema自动更新mutation、输入类型等资源,此时CreateItemsInput会包含categoryId字段,调用时即可正常关联分类。

原理说明

DynamoDB是NoSQL数据库,Amplify通过外键字段而非嵌入对象来建立模型关联。手动定义输入类型会与Amplify自动生成的内容冲突,导致push失败。使用@connection指令后,Amplify会自动处理关联逻辑,生成正确的输入和查询类型。

内容的提问来源于stack exchange,提问作者MizzyV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 16:25:35