Python 为什么在批处理写入DynamoDB时,有时会收到“超出项目大小”消息?
我有一个DynamoDB表,它的项是长字符串。这些字符串是转换为字符串的JSON消息 每个JSON消息下面都有一个唯一的id eId,用作哈希键 如果一个字符串比下面的某个max maxlen长,我会将其拆分为多个片段,并为每个片段创建单独的项,然后创建一个引用这些片段的父消息。通过这种方式,我试图避免创建大于64K限制的项目 我将项目收集到长度为25的批次中,然后批量写入表中 我没有使用maxlen=30000。仍然不时地,批写入抛出项目大小超出限制的异常。以下是拆分代码:Python 为什么在批处理写入DynamoDB时,有时会收到“超出项目大小”消息?,python,json,amazon-dynamodb,Python,Json,Amazon Dynamodb,我有一个DynamoDB表,它的项是长字符串。这些字符串是转换为字符串的JSON消息 每个JSON消息下面都有一个唯一的id eId,用作哈希键 如果一个字符串比下面的某个max maxlen长,我会将其拆分为多个片段,并为每个片段创建单独的项,然后创建一个引用这些片段的父消息。通过这种方式,我试图避免创建大于64K限制的项目 我将项目收集到长度为25的批次中,然后批量写入表中 我没有使用maxlen=30000。仍然不时地,批写入抛出项目大小超出限制的异常。以下是拆分代码: mStr = js
mStr = json.dumps(m,encoding='utf-8', ensure_ascii=False, sort_keys=True)
lStr = len(mStr)
if lStr > maxlen:
np = int(math.ceil(float(lStr)/maxlen))
log.info("Splitting message with id=%s of len=%d into %d pieces of upto %d" % (eId, lStr, np, maxlen))
start=0
parentMessage = ""
for ip in range(np):
fin=(ip+1)*maxlen
ss = mStr[start:fin]
eId_ss = eId + ("-part%dof%d" % (ip+1, np))
item_data = {"split" : "0", "message" : ss}
item = createNewItem(table,eId_ss,item_data)
csP = cPickle.dumps(item)
szP = sys.getsizeof(csP)
log.info("%s: [%d : %d] = %d chars, item size %d" % (eId_ss,start,fin,len(ss),szP))
items.append(item)
item_eIds.append(eId_ss)
parentMessage += (eId_ss + ";")
start=fin
item_data = {"split" : "1", "message" : parentMessage}
item = createNewItem(table,eId,item_data)
items.append(item)
item_eIds.append(eId)
else:
我注意到的是,sys.getsizeofcsP行不时产生的值似乎比字符串ss的长度大4倍左右。这种情况并不经常发生,但我在日志中看到了。所以我假设它不时会生成一个大于64K的项目
一、 当然,我们可以继续降低maxlen。但由于我不了解大型项目是如何生成的,我不知道选择什么价值。另外,maxlen的值越低,意味着会有更多的消息被拆分,这会降低我的代码速度
问题:
1.为什么它有时会生成比它们所包装的字符串大得多的项?
2.更重要的是,是否有一种可靠的方法可以确保我的物品不会太大,而不必将maxlen降低到可笑的低值
Thx
aaaa您必须重新构建数据结构。Dynamo DB的项目限制为64KB,这还包括Atributes等,因此有效大小更小 DynamoDB中的限制-亚马逊DynamoDB: 这说明了如何重新构造数据以在这些限制内工作,如gzip等
使用项目的指导原则-Amazon DynamoDB:您计算的长度实际上是字符串中的字符数。由于您使用的是UTF-8,因此单个字符的长度最多可达4字节,这就是为什么有时您会看到比预期大约4倍的消息 如果要在Python中检查字节大小,可以使用:lenmStr.encode'utf-8'