【问题标题】:Query DynamoDB by GSI using AppSync SDK and Amplify CLI通过 GSI 使用 AppSync SDK 和 Amplify CLI 查询 DynamoDB
【发布时间】:2021-03-21 23:28:03
【问题描述】:

我正在尝试使用 AWS' 通过 AWS AppSync 查询 DynamoDB 表 Android AppSync SDK 和 Amplify CLI。我正在查询一个全球 二级索引 (GSI)。我收到一个错误:

表达式块 '$[query]' 需要一个表达式

我找到了a similar issue,这表明 下面的修复。但是,它对我不起作用:

我的schema.graphql 是:

type olatexOrders @model
@key(fields: ["PK", "SK"])
@key(name: "GSI-item-1", fields: ["GSIPKitem1", "GSISKitem1" ], queryField: "olatexOrdersByGSIPKitem1AndGSISKitem1")
@key(name: "GSI-order-1", fields: ["GSIPKorder1", "GSISKorder1" ], queryField: "olatexOrdersByGSIPKorder1AndGSISKorder1")
{
    PK: String!
    SK: String!
    GSIPKitem1: String
    GSISKitem1: String
    GSIPKorder1: String
    GSISKorder1: String
    ... and many more fields not relevant for this case
}

哈希键(主键 + 辅助键)和两个 GSI(GSI-item-1, GSI-order1) 在 DynamoDB 中正确创建。我也可以查询我的 使用 GSI 来自 AppSync 的 DynamoDB 表:

query MyQuery {
  olatexOrdersByGSIPKorder1AndGSISKorder1(GSIPKorder1: "IN_PROGRESS") {
    nextToken
    items {
      GSIPKorder1
      GSISKorder1
    }
  }
}

但是,当我尝试在内部使用自动生成的放大类时,它不起作用 我的安卓应用,如下:

private void query() {
    AwsClientFactory.getInstance(context)
        .query(OlatexOrdersByGsipKorder1AndGsisKorder1Query
            .builder()
            .gSIPKorder1(ORDER_STATUS_IN_PROGRESS)
            .limit(200)
            .build())
        .responseFetcher(AppSyncResponseFetchers.NETWORK_ONLY)
        .enqueue(callback);
}

我遇到了上述相同的错误。阅读相关内容后 问题,我的理解是有一些 GSI 实施方式的错误/不一致/限制 AppSync,因此您不仅需要指定主键 GSI,但排序键和排序顺序也是如此。有了这些知识, 为了测试,我将我的函数重写为:

private void query() {
    AwsClientFactory.getInstance(context)
        .query(OlatexOrdersByGsipKorder1AndGsisKorder1Query
            .builder()
            .gSIPKorder1(ORDER_STATUS_IN_PROGRESS)
            .gSISKorder1(ModelStringKeyConditionInput.builder().beginsWith("K").build())
            .sortDirection(ModelSortDirection.DESC)
            .limit(200)
            .build())
        .responseFetcher(AppSyncResponseFetchers.NETWORK_ONLY)
        .enqueue(callback);
}

不幸的是,我仍然遇到同样的错误:

表达式块 '$[query]' 需要一个表达式

我使用的是 Amplify CLI 版本 4.27.2。 我们将不胜感激所有帮助!

编辑 1
我试图简化我的案例。我创建了只有一列的 GSI。请参阅下面的schema.graphql

type olatexOrders @model
@key(fields: ["PK", "SK"])
@key(name: "GSI-item-1", fields: ["GSIPKitem1"], queryField: "olatexOrdersByGSIItem")
@key(name: "GSI-order-1", fields: ["GSIPKorder1"], queryField: "olatexOrdersByGSIOrder")
{
    PK: String!
    SK: String!
    GSIPKitem1: String
    GSIPKorder1: String
    ... and many more fields not relevant for this case
}

现在我正在尝试使用以下代码通过 Amplify 和 AppSync 查询我的发电机表:

public class GetInProgressOrders {

    private GraphQLCall.Callback<OlatexOrdersByGsiOrderQuery.Data> callback = new GraphQLCall.Callback<OlatexOrdersByGsiOrderQuery.Data>() {
        @Override
        public void onResponse(@Nonnull Response<OlatexOrdersByGsiOrderQuery.Data> response) {
            try{
                Log.d("MyTest", "TST response error: "+errors.get(0).message());
            }
            catch (Exception e){
                Log.e("MyTest", e.getMessage())
            }
        }

        @Override
        public void onFailure(@Nonnull ApolloException e) {
            Log.e("MyTest", e.getMessage())
        }
    };

    private void query(Context context){
        AWSAppSyncClient awsClient = AwsClientFactory.getInstance(context);
        
        OlatexOrdersByGsiOrderQuery tmpQuery = OlatexOrdersByGsiOrderQuery
                .builder()
                .gSIPKorder1(ORDER_STATUS_IN_PROGRESS)
                .build();

        awsClient.query(
                tmpQuery
            )
                .responseFetcher(AppSyncResponseFetchers.NETWORK_ONLY)
                .enqueue(callback);
    }
}

执行上面的操作会出现与之前相同的错误:

TST response error: Expression block '$[query]' requires an expression

这让我觉得我做错了什么。基本上我无法通过 GSI 在 Amplify 中查询表。不幸的是,我没有看到我的错误。
问候

【问题讨论】:

    标签: amazon-dynamodb aws-amplify aws-appsync aws-amplify-cli amazon-dynamodb-index


    【解决方案1】:

    这并不完全是答案,而是真正有效的解决方法。
    事实证明,我有多个问题,有些记录得更好,有些更糟。我为修复代码所做的事情:

    1. 对于从 Android 应用程序到 AWS AppSync 的通信,请使用 Amplify 类,而不是使用 AWSAppSyncClient 类。
    2. 在 schema.graphql 中,不要只使用大写字母的字段(在我的情况下,使用 PK 和 SK 使用 pk 和 sk)
    3. 在 schema.graphql 中不要创建以小写开头的类型
    4. 创建ID的id列!输入(即使你根本不需要)

    综上所述,请参阅我的 schema.graphql 实际有效:
    type OlatexOrders @model
    
    @key(fields: ["pk", "sk"])
    @key(name: "GSI-item-1", fields: ["gsi_pk_item_1", "gsi_sk_item_1"], queryField: "olatexOrdersByGSIItem")
    @key(name: "GSI-order-1", fields: ["gsi_pk_order_1", "gsi_sk_order_1"], queryField: "olatexOrdersByGSIOrder")
    {
        pk: String!
        sk: String!
        gsi_pk_item_1: String
        gsi_sk_item_1: String
        gsi_pk_order_1: String
        gsi_sk_order_1: String
        ... different not relevant fields
        id: ID!
    }
    

    我在 Android 应用中的查询:

    Amplify.API.query(
    ModelQuery.list(OlatexOrders.class, OlatexOrders.GSI_PK_ORDER_1.eq(ORDER_STATUS_IN_PROGRESS)),
                    response -> {
                        if(response.hasErrors())
                            Log.i("TestTag", "Errors: " + response.getErrors().get(0));
    
                        if(response.hasData()){
                            for(OlatexOrders orders: response.getData()){
                                inProgressOrdersNames.add(orders.getGsiSkOrder_1());
                            }
                        }
                        else{
                            Log.i("TestTag", "No data");
                        }
                    },
                    error -> Log.e("TestTag", "Error", error)
            );
    

    问候!

    【讨论】:

      猜你喜欢
      • 2020-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多