Python DynamoDB-通过多个键获取项目

Python DynamoDB-通过多个键获取项目,python,amazon-dynamodb,boto3,dynamodb-queries,Python,Amazon Dynamodb,Boto3,Dynamodb Queries,最近开始使用DynamoDB,通过多个键获取数据时遇到问题 我正在尝试从表中获取多个项目 我的表架构定义如下: { "AttributeDefinitions": [ { "AttributeName": "id", "AttributeType": "S" }, { "AttributeName": "date", "AttributeType": "S" } ], "KeySchema": [

最近开始使用
DynamoDB
,通过多个键获取数据时遇到问题

我正在尝试从表中获取多个项目

我的表架构定义如下:

{
  "AttributeDefinitions": [
    {
      "AttributeName": "id",
      "AttributeType": "S"
    },
    {
      "AttributeName": "date",
      "AttributeType": "S"
    }
  ],
  "KeySchema": [
    {
      "AttributeName": "id",
      "KeyType": "HASH"
    },
    {
      "AttributeName": "date",
      "KeyType": "RANGE"
    }
  ],
  ...
}
我有一个id筛选列表和每个id的日期范围:

[
    { "id": "abc", "start_date": "24/03/2020", "end_date": "26/03/2020" },
    { "id": "def", "start_date": "10/04/2020", "end_date": "20/04/2020" },
    { "id": "ghi", "start_date": "11/04/2020", "end_date": "11/04/2020" }
]
我需要获取与筛选器列表匹配的所有项目

问题是我不能使用
Query
,因为
KeyConditionExpression
只接受一个分区键(我需要将它与整个筛选器列表匹配)

该条件必须对单个分区键值执行相等测试

我不能使用
BatchGetItem
,因为它需要精确的键(并且我需要排序键
键(“日期”)的日期范围。介于(开始日期、结束日期)

键-定义表中特定项的主键属性值数组。对于每个主键,必须提供所有键属性。例如,对于一个简单的主键,您只需要提供分区键值。对于复合键,必须同时提供分区键值和排序键值

我有点迷路了。。。 有没有一种方法可以通过范围查询(通过单个请求,而不是来自循环的多个请求)通过多个键获取数据


您是否建议更改表?

您可以使用table.scan获取多条记录。见文件

下面是一个示例代码:

import boto3

# Get the service resource.
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('tablename')

response = table.scan(
FilterExpression=Attr('first_name').begins_with('J') & Attr('account_type').eq('super_user')
)
items = response['Items']
print(items)

您需要对每个唯一的
id
进行一次查询。每个查询都应该包括一个键条件表达式,该表达式在
id
分区键和
date
排序键上具有相等的值范围,如下所示:

#id = :id AND #date BETWEEN :startdate AND :enddate

不要对此使用
scan
。随着表的增长,性能将下降。

使用多个
查询
请求不是一个问题吗?例如,如果我需要按20个ID对其进行筛选,那么我将向表发送20个请求,而不是1个请求和多个ID,这将提高我的请求率。。。另一方面,我没有找到任何其他方法(除了
scan
,这在这里不是一个选项),所以我猜这是唯一的选项..?因为您有多个分区键,并且您的日期范围不同,我不知道有什么方法可以在一个查询中满足这一点。即使添加GSI也无济于事。但是,您可以并行进行查询,因为它们可能会访问不同的分区,这将减少您的总延迟。谢谢您的回答!然而,
scan
操作非常“昂贵”,因为它在获取数据之后和返回数据之前应用过滤器-所以不幸的是,这不是我的选择。