Python - 如何使用主键和排序键在 GSI 上查询 DynamoDB
Python - How to query DynamoDB on GSI using primary and sort key
好吧,正如标题所暗示的那样,我想使用 GSI 以及主键和排序键(均来自 GSI)在我的 DynamoDB table 上进行查询。我尝试了一些方法来做到这一点,但都成功了。
我有一个 table 和 url-date-index
,url
是来自 GSI 的主键,date
是排序键。
我尝试了以下方法:
将KeyConditionExpression
与&
比较器一起使用:
这个检索到我的错误:TypeError: expected string or bytes-like
boto3.resource('dynamodb').Table('table').query(
IndexName='url-date-index',
KeyConditionExpression=conditions.Key('url')).eq(url) & conditions.Key('date')).eq(date)
)
使用 KeyConditionExpression
和 FilterExpression
:
这检索到以下错误:Filter Expression can only contain non-primary key attributes
boto3.resource('dynamodb').Table('table').query(
IndexName='url-date-index',
KeyConditionExpression=conditions.Key('url')).eq(url),
FilterExpression=conditions.Key('date')).eq(date)
)
使用 ExpressionAttributeNames
、ExpressionAttributeValues
和 KeyConditionExpression
:
这会返回任何内容,甚至不匹配 table 上的 url
和 date
的项目。
boto3.resource('dynamodb').Table('table').query(
IndexName='url-date-index',
ExpressionAttributeNames={
'#n0': 'url',
'#n1': 'date'
},
ExpressionAttributeValues={
':v0': url,
':v1': date
},
KeyConditionExpression='(#n0 = :v0) AND (#n1 = :v1)'
)
有谁知道我做错了什么或者我可以做些什么来完成这项工作。
query 是一个带有一些命名参数的函数(IndexName
、KeyConditionExpression
、...)。
让我们尝试像普通函数一样调用带有命名参数的函数:
boto3.resource('dynamodb').Table('table').query(
IndexName='url-date-index',
KeyConditionExpression=conditions.Key('url')).eq(url) & conditions.Key('date')).eq(date)
)
在您的特定用例中,您需要使用 ExpressionAttributeNames
,因为您的属性名称 url
和 date
是 reserved words in DynamoDB.
DynamoDB docs on querying secondary idnexes 给出了结构正确的查询示例,我们可以将其应用于您的情况:
以此为指导,我们可以构造您的查询操作的参数应该是什么样子。例如
{
"TableName": "table",
"IndexName": "url-date-index",
"KeyConditionExpression": "#pk = :pk And #sk = :sk",
"ExpressionAttributeNames": {"#pk":"url","#sk":"date"},
"ExpressionAttributeValues": {":pk": {"S":url},":sk": {"S":date}}}
}
如果这仍然不适合您,请考虑查看 NoSQL Workbench For DynamoDB。在众多有用的功能中,它有一个 Operation Builder,可帮助您使用图形界面构建 DynamoDB 操作。您甚至可以 运行 对实时数据库进行操作。一旦您的操作按您希望的方式运行,该工具就可以将操作转换为完整的 Phython、Javascript(Node) 或 Java 代码示例,您可以使用它来查看操作是如何进行的建造。
好吧,正如标题所暗示的那样,我想使用 GSI 以及主键和排序键(均来自 GSI)在我的 DynamoDB table 上进行查询。我尝试了一些方法来做到这一点,但都成功了。
我有一个 table 和 url-date-index
,url
是来自 GSI 的主键,date
是排序键。
我尝试了以下方法:
将
KeyConditionExpression
与&
比较器一起使用:这个检索到我的错误:
TypeError: expected string or bytes-like
boto3.resource('dynamodb').Table('table').query(
IndexName='url-date-index',
KeyConditionExpression=conditions.Key('url')).eq(url) & conditions.Key('date')).eq(date)
)
使用
KeyConditionExpression
和FilterExpression
:这检索到以下错误:
Filter Expression can only contain non-primary key attributes
boto3.resource('dynamodb').Table('table').query(
IndexName='url-date-index',
KeyConditionExpression=conditions.Key('url')).eq(url),
FilterExpression=conditions.Key('date')).eq(date)
)
使用
ExpressionAttributeNames
、ExpressionAttributeValues
和KeyConditionExpression
:这会返回任何内容,甚至不匹配 table 上的
url
和date
的项目。
boto3.resource('dynamodb').Table('table').query(
IndexName='url-date-index',
ExpressionAttributeNames={
'#n0': 'url',
'#n1': 'date'
},
ExpressionAttributeValues={
':v0': url,
':v1': date
},
KeyConditionExpression='(#n0 = :v0) AND (#n1 = :v1)'
)
有谁知道我做错了什么或者我可以做些什么来完成这项工作。
query 是一个带有一些命名参数的函数(IndexName
、KeyConditionExpression
、...)。
让我们尝试像普通函数一样调用带有命名参数的函数:
boto3.resource('dynamodb').Table('table').query(
IndexName='url-date-index',
KeyConditionExpression=conditions.Key('url')).eq(url) & conditions.Key('date')).eq(date)
)
在您的特定用例中,您需要使用 ExpressionAttributeNames
,因为您的属性名称 url
和 date
是 reserved words in DynamoDB.
DynamoDB docs on querying secondary idnexes 给出了结构正确的查询示例,我们可以将其应用于您的情况:
以此为指导,我们可以构造您的查询操作的参数应该是什么样子。例如
{
"TableName": "table",
"IndexName": "url-date-index",
"KeyConditionExpression": "#pk = :pk And #sk = :sk",
"ExpressionAttributeNames": {"#pk":"url","#sk":"date"},
"ExpressionAttributeValues": {":pk": {"S":url},":sk": {"S":date}}}
}
如果这仍然不适合您,请考虑查看 NoSQL Workbench For DynamoDB。在众多有用的功能中,它有一个 Operation Builder,可帮助您使用图形界面构建 DynamoDB 操作。您甚至可以 运行 对实时数据库进行操作。一旦您的操作按您希望的方式运行,该工具就可以将操作转换为完整的 Phython、Javascript(Node) 或 Java 代码示例,您可以使用它来查看操作是如何进行的建造。