Aws之DynamoDb批量读取遇到的坑
最近要写个读取aws大量数据的需求,需要操作多个DynamoDb数据库,这时候沿路就遇到了许多问题
1.从数据库直接扫描读取全部数据
第一步连接数据库
# -*- coding: utf-8 -*-
import boto3
from boto3.dynamodb.conditions import Attr
dynamodb = boto3.resource('dynamodb', region_name='us-east-1',
aws_access_key_id='',
aws_secret_access_key='')#连接数据库
table_handle = dynamodb.Table('mytable')#获取对应表的handle
因为aws 通过scan全盘扫描数据一次只能给限定大小的数据一般是1M所以必须分页获取数据,所以需要记录最新数据对应的主键last_evaluated_key
last_evaluated_key = None #最新主键
while True:
if last_evaluated_key is None:
response = table_handle.scan(
FilterExpression=Attr('type').eq('email')
)
else:
response = table_handle.scan(
FilterExpression = Attr('type').eq('email'),
ExclusiveStartKey = last_evaluated_key#通过主键获取扫描初始位置
)
items = response['Items']#这就是每次scan获取的所有数据list
if response.has_key('LastEvaluatedKey'):
last_evaluated_key = response['LastEvaluatedKey']
else:
break
2.通过索引批量从数据库获取数据
client = boto3.client('dynamodb', region_name='us-east-1',
aws_access_key_id='',
aws_secret_access_key='')#连接数据库
response = client.batch_get_item(
RequestItems=dic,#dic位查询的字典
ReturnConsumedCapacity='TOTAL'
)
response=response['Responses']
items = response['要查找数据表名字']
利用boto3库的batch_get_item方法,每次能最多获取100个item
因为这个方法如果存在排序主键所以查询字段必须要带上排序主键
需要把所有要查询数据对应的主键加上存在的排序主键拼接起来
response = client.batch_get_item(#这是boto3官方给的数据结构
RequestItems={
'string': {#要查找数据表的名字
'Keys': [#主键 key对应的是个List,我们要查询的数据就是塞进这个list
{
'string': {#一个字段的名字,如主键名字
'S': 'string',#字符串
'N': 'string',#数字
'B': b'bytes',#二进制数
'SS': [
'string',#字符串集
],
'NS': [#数字集
'string',
],
'BS': [#二进制数集
b'bytes',
],
'M': {#映射
'string': {'... recursive ...'}
},
'L': [#列表
{'... recursive ...'},
],
'NULL': True|False,
'BOOL': True|False
},
{
'string': {#另一个字段的名字,如排序主键
'S': 'string',
'N': 'string',
'B': b'bytes',
'SS': [
'string',
],
'NS': [
'string',
],
'BS': [
b'bytes',
],
'M': {
'string': {'... recursive ...'}
},
'L': [
{'... recursive ...'},
],
'NULL': True|False,
'BOOL': True|False
}
},
},
#在这里接下来拼下一个数据
],
'AttributesToGet': [
'string',
],
'ConsistentRead': True|False,
'ProjectionExpression': 'string',#要获取表内字段可以为多个比如两个字段'id,name'
'ExpressionAttributeNames': {
'string': 'string'
}
}
},
ReturnConsumedCapacity='INDEXES'|'TOTAL'|'NONE'
)
第一层 查询字段具体数据
search_dic={
'id'{
'N' : '20191106'
},
'name'{
's' : '张三'
}
}
第二层 查询数据拼接,最多拼接一百个
mytable={
'Keys': [search_dic1,search_dic2,search_dic3]
'ProjectionExpression': 'id,name,grade'
}
send_dic={
'mytable':mytable
}
第三层 数据提交后获取
response = client.batch_get_item(#这是boto3官方给的数据结构
RequestItems=send_dic
)
response=response['Responses']
items = response['mytable']
for item in items:
grade=item['grade']['N']
print (grade)
这样就获取了100个对应的数据,相比一次一次获取速度提升很多而且操作费用也降低很多