用于Dynamodb的boto3中FilterExpression中的列表推导

时间:2016-10-22 16:55:22

标签: amazon-dynamodb boto3 nosql

所以我在dynamodb的数据库中有一些项目,看起来有点像这样,其中name是主键

'name': {'S': 'bob'},
'users': {'L': [
    {'M': {
        'user_id': {'S': 'xxx'},
        'share': {'N': '1'}}},
    {'M': {
        'user_id': {'S': 'yyy'},
        'share': {'N': '4'}}}]}

现在我的问题是用户是一个字典列表,我想知道当列表中有特定的name时,我是否有任何方法可以扫描表格以获取user_id用户。

我知道在python中我会做一个列表理解只是得到一个user_id的列表然后只做一个user_id in [user['user_id'] for user in users]这将是测试,但我不确定如何在DynamoDB扫描FilterExpression中执行此操作。

我只是想避免让Item看起来像这样:

'name': {'S': 'bob'},
'users': {'L': [
    {'M': {
        'user_id': {'S': 'xxx'},
        'share': {'N': '1'}}},
    {'M': {
        'user_id': {'S': 'yyy'},
        'share': {'N': '4'}}}]}
'user_ids': {'L': [
    {'S': 'xxx'},
    {'S': 'yyy'}]}

因为它感觉就像一个所谓的“代码味”。但这样可以解决问题,因为过滤器表达式只是:user_id in user_ids

1 个答案:

答案 0 :(得分:1)

DynamoDB没有功能来过滤列表数据类型中地图中的数据。用户列表具有用户标识和共享属性。如果您知道用户ID和共享的值,则可以使用 CONTAINS 运算符来过滤数据。

请注意,正如您在OP中提到的,DynamoDB中的IN运算符无法像这样使用。请参阅下面的说明。

  

IN:检查两组中的匹配元素。

     

AttributeValueList可以包含一个或多个String类型的AttributeValue元素,   数字或二进制(不是集合类型)。比较这些属性   针对项目的现有set type属性。如果有任何要素   输入集存在于item属性表达式中   评估为真。

var params = {
        TableName: "tablenames",    
        FilterExpression: "contains (#users, :usersDetails)",
        ExpressionAttributeNames: { '#users'  : 'users'},
        ExpressionAttributeValues: {
            ":usersDetails": {'user_id' : 'xxx', 'share' : 1}

        }
};