在 Boto DynamoDB Scan 中从迭代器对象中解压不确定数量的属性
Unpack uncertain number of attributes from iterator object in Boto DynamoDB Scan
所以我正在使用 AWS DynamoDB,因为可以说是 NoSQL 特性和具有模糊数量 'columns' 的能力。为此,我使用 boto 与数据库进行交互,但事实证明动态获取不同数量的 columns/attributes 很困难。
我的数据库 table 大多没有明确的架构(为什么我要使用 NoSQL),并且大多数行的属性与其他行不同。我知道 Dynamo 可以做到这一点,但我需要一种通过简单扫描获取所有键/columns/attributes 的方法。我的数据库不大,根本不会增长太多,所以我不担心 scan/query 的效率。
我的table(差不多):
{'name': 'John', 'email': '12@34.com'}
{'name': 'Charlie', 'email': '34@56.com', 'dislikes': 'people's knees'}
{'name': 'Joe', 'email': '78@90.com', 'hobby': 'golf'}
如您所见,每一行都有不同的属性。
我的 boto 测试脚本
import os
import boto.dynamodb2
from boto.dynamodb2.table import Table
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
def connect():
conn = boto.dynamodb2.connect_to_region(
'us-east-1',
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
return conn
conn = connect()
table = Table('table1', connection=conn)
scan = table.scan()
这个returns一个迭代器对象
<boto.dynamodb2.items.Item object at ....>
要解析这个对象,必须知道属性名称,对象不能用数字索引:
for i in scan:
print i['name']
# John
# Charlie
# Joe
for i in scan:
print i[0]
# None
# None
# None
当我使用多个变量进行解包时,它可以工作,但我必须像这样专门定义变量:
for i, j, k in scan:
print i, j, k
这适用于具有三列但只有三列的行。
我想要做的是遍历每一行并取回其对应的列,这可能与下一行不同。我遇到了困难,非常感谢任何反馈。
找到问题了!
所以我觉得很蠢。这个答案的一个关键部分是在扫描时调用 .items() 。这使得扫描实际上可以按照我想要的方式进行迭代。
我想要一个包含各种大小字典的字典,所以我需要创建一个范围更广的字典来容纳每个 row/person 和一个更窄的范围来添加每个细节(key/column 及其值).您的数据结构可能与我的不同,但希望这能让您指明正确的方向。
...
scan = table.scan()
#outer-most dict for each row
dict0 = {}
# enumerate so each row can be appended to dict0 using index
for index, row in enumerate(scan):
# inner-most dict for each key/value pair
dict1 = {}
for key, value in row.items():
dict1[str(key)] = str(value)
dict0[index] = dict1
我使用 str() 是因为我在结果中得到了 unicode u' ' 字符。
遍历数据大部分是相同的,我们只是省略了字典内容。
for index, keyValues in dict0.items():
print index
for key, value in keyValues.items():
print "\t {}: {}".format(key, value)
打印出这样的东西(按添加时间排序):
0
"hobby": "golf"
"email": "78@90.com"
"name" : "Joe"
1
'dislikes': "people's knees"
"name" : "Charlie"
"email": "34@56.com"
2
"name" : "John"
"email": "12@34.com"
所以我正在使用 AWS DynamoDB,因为可以说是 NoSQL 特性和具有模糊数量 'columns' 的能力。为此,我使用 boto 与数据库进行交互,但事实证明动态获取不同数量的 columns/attributes 很困难。
我的数据库 table 大多没有明确的架构(为什么我要使用 NoSQL),并且大多数行的属性与其他行不同。我知道 Dynamo 可以做到这一点,但我需要一种通过简单扫描获取所有键/columns/attributes 的方法。我的数据库不大,根本不会增长太多,所以我不担心 scan/query 的效率。
我的table(差不多):
{'name': 'John', 'email': '12@34.com'}
{'name': 'Charlie', 'email': '34@56.com', 'dislikes': 'people's knees'}
{'name': 'Joe', 'email': '78@90.com', 'hobby': 'golf'}
如您所见,每一行都有不同的属性。
我的 boto 测试脚本
import os
import boto.dynamodb2
from boto.dynamodb2.table import Table
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
def connect():
conn = boto.dynamodb2.connect_to_region(
'us-east-1',
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
return conn
conn = connect()
table = Table('table1', connection=conn)
scan = table.scan()
这个returns一个迭代器对象
<boto.dynamodb2.items.Item object at ....>
要解析这个对象,必须知道属性名称,对象不能用数字索引:
for i in scan:
print i['name']
# John
# Charlie
# Joe
for i in scan:
print i[0]
# None
# None
# None
当我使用多个变量进行解包时,它可以工作,但我必须像这样专门定义变量:
for i, j, k in scan:
print i, j, k
这适用于具有三列但只有三列的行。
我想要做的是遍历每一行并取回其对应的列,这可能与下一行不同。我遇到了困难,非常感谢任何反馈。
找到问题了!
所以我觉得很蠢。这个答案的一个关键部分是在扫描时调用 .items() 。这使得扫描实际上可以按照我想要的方式进行迭代。
我想要一个包含各种大小字典的字典,所以我需要创建一个范围更广的字典来容纳每个 row/person 和一个更窄的范围来添加每个细节(key/column 及其值).您的数据结构可能与我的不同,但希望这能让您指明正确的方向。
...
scan = table.scan()
#outer-most dict for each row
dict0 = {}
# enumerate so each row can be appended to dict0 using index
for index, row in enumerate(scan):
# inner-most dict for each key/value pair
dict1 = {}
for key, value in row.items():
dict1[str(key)] = str(value)
dict0[index] = dict1
我使用 str() 是因为我在结果中得到了 unicode u' ' 字符。
遍历数据大部分是相同的,我们只是省略了字典内容。
for index, keyValues in dict0.items():
print index
for key, value in keyValues.items():
print "\t {}: {}".format(key, value)
打印出这样的东西(按添加时间排序):
0
"hobby": "golf"
"email": "78@90.com"
"name" : "Joe"
1
'dislikes': "people's knees"
"name" : "Charlie"
"email": "34@56.com"
2
"name" : "John"
"email": "12@34.com"