【问题标题】:Unpack uncertain number of attributes from iterator object in Boto DynamoDB Scan在 Boto DynamoDB Scan 中从迭代器对象中解压缩不确定数量的属性
【发布时间】:2015-07-13 16:38:30
【问题描述】:

所以我使用 AWS DynamoDB 是因为它具有 NoSQL 特性,并且可以说具有模糊数量的“列”。为此,我使用 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

这适用于三列但只有三列的行。

我想要做的是遍历每一行并取回其对应的列,这可能与下一行不同。我遇到了困难,非常感谢任何反馈。

【问题讨论】:

    标签: python iterator generator amazon-dynamodb boto


    【解决方案1】:

    找到问题了!

    所以我觉得很愚蠢。这个答案的一个关键部分是扫描时调用的 .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' ' 字符。

    对数据进行迭代几乎是相同的,我们只是省略了字典的内容。

    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"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-30
      • 2015-08-28
      • 2020-08-15
      • 1970-01-01
      • 2019-11-17
      • 2013-07-14
      • 2021-10-03
      相关资源
      最近更新 更多