AWS BotoCore错误 - AttributeValue可能不包含空字符串

时间:2017-07-31 17:54:16

标签: python dictionary amazon-s3 amazon-dynamodb boto

我正在尝试使用旧事件存储中的数据填充DynamoDB数据库 由PostgreSQL数据库组成。在它运行了大部分数据库条目后,尝试调用put_item函数时抛出了此错误。

botocore.exceptions.ClientError: -

  

调用PutItem操作时发生错误(ValidationException):一个或多个参数值无效:AttributeValue可能不包含空字符串

我决定重新运行代码,通过在插入之前转储所有表属性来查看发生的情况。

我可以看到唯一的“空字符串”位于字典的answer_string属性中,名为details,见下文: -

Importing event type 5 completed by user: 1933
1933 5 {'answer': {'difficulty': 1, 'answer_string': ''}, 'card_id': n 
'13448', 'review_id': '153339', 'time_spent': 2431}
62 153339
2017-01-18 00:46:48.373009+00:00 2017-01-18 00:46:48.364217+00:00

我很确定这是导致错误抛出的原因,因为没有其他表属性不正确。

我的问题是details字典可以来自几十个不同的位置,每个details字典可以有不同的属性 - 具有answer_string属性的字典只是许多可能字典中的一个配置。我无法检查字典的所有可能配置并验证它们都没有空字符串。

有没有办法我可以对字典进行一次全面检查,看看它的任何一部分是否为空?

4 个答案:

答案 0 :(得分:3)

如果您想获得一个仅包含所有具有空值的键的字典,您只需将dictionary comprehension应用于details - dict即可获得具有空值的所有键值对。 E.g:

empty_values = {key: value for key, value in details.items() if not value}

如果您想要使用空值过滤掉键值对,那么您将留下所有键都具有值的字典,只需使用相同的理解而不使用not

details = {key: value for key, value in details.items() if value}

答案 1 :(得分:2)

@PedoDorf的函数为我工作,尽管我必须添加检查,因为有时在接收字符串时它会返回“ TypeError:字符串索引必须为整数”

def removeEmptyString(dic):
  if isinstance(dic, str):
    if dic == "":
      return None
    else:
      return dic

  for e in dic:
    if isinstance(dic[e], dict):
      dic[e] = removeEmptyString(dic[e])
    if (isinstance(dic[e], str) and dic[e] == ""):
      dic[e] = None
    if isinstance(dic[e], list):
      for entry in dic[e]:
        removeEmptyString(entry)
  return dic

谢谢

答案 2 :(得分:0)

或者,如果您想将所有空字符串替换为None值:

def removeEmptyString(dic):
    for e in dic:
        if isinstance(dic[e], dict):
            dic[e] = removeEmptyString(dic[e])
        if (isinstance(dic[e], str) and dic[e] == ""):
            dic[e] = None
        if isinstance(dic[e], list):
            for entry in dic[e]:
                removeEmptyString(entry)
    return dic

dictionaryWithEmptyStringsReplacedWithNone = removeEmptyString(dicrionaryWithEmptyStrings)

它远非完美,但可以。

答案 3 :(得分:0)

如果您需要考虑嵌套对象并进行清理,请尝试一下。需要一些递归:

def clean_ddb_data(obj):
    cleaned = {}
    for k, v in obj.items():
        if isinstance(v, dict):
            cleaned[k] = clean_ddb_data(v)
        elif isinstance(v, str):
            if len(v) > 0:
                cleaned[k]=v
        else:
            cleaned[k]=v
    return cleaned