我正在尝试为我拥有的dynamodb表创建一个分页端点。但我已经尝试了所有方法来使exclusiveStartKey成为正确的类型以使其正常工作。然而,我尝试的所有东西似乎都不起作用。
示例代码:
func GetPaginator(tableName string, limit int32, lastEvaluatedKey string) (*dynamodb.ScanPaginator, error) {
svc, err := GetClient()
if err != nil {
logrus.Error(err)
return nil, err
}
input := &dynamodb.ScanInput{
TableName: aws.String(tableName),
Limit: aws.Int32(limit),
}
if lastEvaluatedKey != "" {
input.ExclusiveStartKey = map[string]types.AttributeValue{
"id": &types.AttributeValueMemberS{
Value: lastEvaluatedKey,
},
}
}
paginator := dynamodb.NewScanPaginator(svc, input)
return paginator, nil
}编辑:
好的,我正在创建一个需要分页的API。接口需要有一个查询参数,可以在其中定义lastEvaluatedId。然后,我可以使用lastEvaluatedId在ScanInput上作为ExclusiveStartKey传递。然而,当我这样做时,我仍然从数据库收到相同的项。我已经创建了一个test.go文件,并将发布以下代码:
package main
import (
"context"
"fmt"
"os"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
)
type PaginateID struct {
ID string `dynamodbav:"id" json:"id"`
}
func main() {
lastKey := PaginateID{ID: "ae82a99d-486e-11ec-a7a7-0242ac110002"}
key, err := attributevalue.MarshalMap(lastKey)
if err != nil {
fmt.Println(err)
return
}
cfg, err := config.LoadDefaultConfig(context.TODO(), func(o *config.LoadOptions) error {
o.Region = os.Getenv("REGION")
return nil
})
if err != nil {
fmt.Println(err)
return
}
svc := dynamodb.NewFromConfig(cfg, func(o *dynamodb.Options) {
o.EndpointResolver = dynamodb.EndpointResolverFromURL("http://localhost:8000")
})
input := &dynamodb.ScanInput{
TableName: aws.String("TABLE_NAME"),
Limit: aws.Int32(1),
ExclusiveStartKey: key,
}
paginator := dynamodb.NewScanPaginator(svc, input)
if paginator.HasMorePages() {
data, err := paginator.NextPage(context.TODO())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(data.Items[0]["id"])
fmt.Println(data.LastEvaluatedKey["id"])
}
}当我运行这段测试代码时。我得到以下输出:
&{ae82a99d-486e-11ec-a7a7-0242ac110002 {}}
&{ae82a99d-486e-11ec-a7a7-0242ac110002 {}}因此,返回的项与我传递给ScanInput.ExclusiveStartKey的Id相同。这意味着它不是从ExclusiveStartKey开始的。每次扫描都从头开始。
发布于 2021-11-18 13:31:31
基本上,您需要做的就是获取LastEvaluatedKey并将其传递给ExclusiveStartKey
您不能使用扫描分页器属性,因为它不是导出的属性,因此我建议您通过调用NextPage来使用返回的页面
在下面的代码片段中,我有一个示例:
func GetPaginator(ctx context.Context,tableName string, limit int32, lastEvaluatedKey map[string]types.AttributeValue) (*dynamodb.ScanOutput, error) {
svc, err := GetClient()
if err != nil {
logrus.Error(err)
return nil, err
}
input := &dynamodb.ScanInput{
TableName: aws.String(tableName),
Limit: aws.Int32(limit),
}
if len(lastEvaluatedKey) > 0 {
input.ExclusiveStartKey = lastEvaluatedKey
}
paginator := dynamodb.NewScanPaginator(svc, input)
return paginator.NextPage(), nil
}请记住,paginator.NextPage(ctx)可以是nil,以防没有更多的页面,或者您可以使用HasMorePages()
发布于 2021-11-18 15:30:33
aws-sdk-go-v2 DynamoDB查询和扫描分页器构造函数有一个错误(see my github issue, includes the fix)。它们不尊重ExclusiveStartKey参数。
作为临时修复,我在本地复制了分页器类型,并在构造函数中添加了一行:nextToken: params.ExclusiveStartKey。
https://stackoverflow.com/questions/70019358
复制相似问题