所以我使用的是AWS DynamoDB,因为它具有NoSQL-ness功能,并且能够使用不明确数量的列#39;可以这么说。为此,我使用boto与数据库进行交互,但是动态地获取不同数量的列/属性证明是困难的。
我的db表大多没有确定的模式(为什么我要使用NoSQL),并且大多数行的属性与其他行不同。我知道Dynamo可以做到这一点,但我需要一种方法来通过简单的扫描获得所有键/列/属性。我的数据库并不大,根本不会增长太多,所以我并不担心扫描/查询的效率。
我的桌子(或多或少):
{'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()
这将返回一个迭代器对象
<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
适用于有三列但只有三列的行。
我希望能够做的是遍历每一行并返回其相应的列,这可能与下一行不同。我碰到了墙,任何反馈都非常感激。
答案 0 :(得分:0)
发现了问题!
所以我感到非常愚蠢。这个答案的关键部分是扫描时调用的.items()。这使得扫描实际上可以按照我想要的方式进行迭代。
我想要一本不同大小字典的字典,所以我需要创建一个更宽的字典来保存每一行/每个人和一个更窄的范围来添加每个细节(键/列及其值)。您的数据结构可能与我的不同,但这有望让您指向正确的方向。
...
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&#39; &#39;我的结果中的字符。
迭代数据大致相同,我们只是遗漏了字典。
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"