这是我通过无服务器框架构建的 DynamoDB 表,为“aaa_id”添加了一个辅助列索引:
Devices:
Type: AWS::DynamoDB::Table
Properties:
TableName: Devices
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: serial
AttributeType: S
- AttributeName: aaa_id
AttributeType: N
KeySchema:
- AttributeName: serial
KeyType: HASH
GlobalSecondaryIndexes:
- IndexName: aaa_id
KeySchema:
- AttributeName: aaa_id
KeyType: HASH
Projection:
ProjectionType: ALL
我想查询我的 DynamoDB 并获取表中列“aaa_id”存在或不为 0(或 null,如果数字类型列甚至可能)的所有项目。有些行不包括它。 最好使用
query
方法而不是 scan
因为我知道它不那么重
我已经研究了几个小时了。请帮助。
我的一些失败尝试:
import json
import boto3
def lambda_handler(event, context):
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Devices')
try:
response = table.query(
IndexName='aaa_id',
FilterExpression='aaa_id <> :empty',
ExpressionAttributeValues={':empty': {'N': '0'}}
)
items = response['Items']
return {
'statusCode': 200,
'body': json.dumps(items)
}
except Exception as e:
print(e)
return {
'statusCode': 500,
'body': json.dumps('Error querying the database')
}
#################################
import json
import boto3
from boto3.dynamodb.conditions import Key, Attr
def lambda_handler(event, context):
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Devices')
try:
response = table.query(
IndexName='aaa_id',
KeyConditionExpression=Key('aaa_id').gt(0) & Attr('aaa_id').not_exists(),
ExpressionAttributeValues={
':empty': {'N': ''}
}
)
data = response['Items']
while 'LastEvaluatedKey' in response:
response = table.query(
IndexName='aaa_id',
KeyConditionExpression=Key('aaa_id').gt(0) & Attr('aaa_id').not_exists(),
ExpressionAttributeValues={
':empty': {'N': ''}
},
ExclusiveStartKey=response['LastEvaluatedKey']
)
data.extend(response['Items'])
return {
'statusCode': 200,
'body': json.dumps(data),
'success': True
}
except Exception as e:
return {
'statusCode': 500,
'body': json.dumps(str(e)),
'success': False
}
#######################
import json
import boto3
from boto3.dynamodb.conditions import Key
def lambda_handler(event, context):
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Devices')
try:
response = table.query(
IndexName='aaa_id-index',
KeyConditionExpression=Key('aaa_id').gt(0)
)
items = response['Items']
while 'LastEvaluatedKey' in response:
response = table.query(
IndexName='aaa_id-index',
KeyConditionExpression=Key('aaa_id').gt(0),
ExclusiveStartKey=response['LastEvaluatedKey']
)
items.extend(response['Items'])
return {
'statusCode': 200,
'body': json.dumps(items),
'success': True
}
except Exception as e:
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)}),
'success': False
}
##################################
import boto3
import json
def lambda_handler(event, context):
dynamodb = boto3.client('dynamodb')
try:
response = dynamodb.query(
TableName="Devices",
IndexName='aaa_id-index',
KeyConditionExpression='aaa_id <> :empty',
# ExpressionAttributeValues={':empty': {'S': ''}}
)
return {
'statusCode': 200,
'body': json.dumps(response['Items']),
'status': 'success'
}
except Exception as e:
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)}),
'status': 'error'
}
你把事情复杂化了。首先,数字类型不能为空,因为 DynamoDB 是无模式的,您只需省略任何值即可。
其次,索引可以是稀疏的。由于您对 0 的项目不感兴趣,因此不要为其设置值,这反过来意味着该项目将不存在于索引中。
然后您只需扫描索引,因为您知道那里的所有值都不为空且不为 0。在这种情况下,扫描是高效的,因为它正在读取您想要的内容。
response = table.scan(
IndexName='aaa_id'
)