Python:限制发布到服务器的JSON字符串的大小

0lvr5msh  于 2023-04-10  发布在  Python
关注(0)|答案(1)|浏览(97)

我正在向一个最大数据上传限制为1 MB的服务器发布数十万条JSON记录。我的记录大小非常可变,从几百字节到几十万字节。

def checkSize(payload):
    return len(payload) >= bytesPerMB 

toSend = []
for row in rows:
    toSend.append(row)
    postData = json.dumps(toSend)
    tooBig = tooBig or checkSize()
    if tooBig:
          sendToServer(postData)

然后发送到服务器。它目前可以工作,但是不断地将toSend转储到jsonified字符串似乎真的很重,几乎100%太多了,尽管我似乎找不到另一种方法。我可以将单个新记录字符串化并记录它们在一起的内容吗?
我相信一定有更干净的方法,但我就是不知道。
谢谢你给予的所有帮助。
这是我现在使用的答案,我在下面的@rsegal的同时想出了它,只是为了清晰和完整而发布(sendToServer只是一个虚拟函数,以显示事情正在正常工作),

import pickle
import json

f = open("userProfiles")
rows = pickle.load(f)
f.close()

bytesPerMB = 1024 * 1024
comma = ","
appendSize = len(comma)

def sendToServer(obj):
    #send to server
    pass

def checkSize(numBytes):
    return numBytes >= bytesPerMB

def jsonDump(obj):
    return json.dumps(obj, separators=(comma, ":"))

leftover = []
numRows = len(rows)
rowsSent = 0

while len(rows) > 0:
    toSend = leftover[:]
    toSendSize = len( jsonDump(toSend) )
    leftover = []
    first = len(toSend) == 0

    while True:
        try:
            row = rows.pop()
        except IndexError:
            break

        rowSize = len( jsonDump(row) ) + (0 if first else appendSize)
        first = False

        if checkSize(toSendSize + rowSize):
            leftover.append(row)
            break

        toSend.append(row)
        toSendSize += rowSize

    rowsSent += len(toSend)
    postData = jsonDump(toSend)
    print "assuming to send '{0}' bytes, actual size '{1}'. rows sent {2}, total {3}".format(toSendSize, len(postData), rowsSent, numRows)
    sendToServer(postData)
h5qlskok

h5qlskok1#

我会做如下的事情:

toSend = []
toSendLength = 0
for row in rows:
    tentativeLength = len(json.dumps(row))
    if tentativeLength > bytesPerMB:
        parsingBehavior # do something about lolhuge files
    elif toSendLength + tentativeLength > bytesPerMB: # it would be too large
        sendToServer(json.dumps(toSend)) # don't exceed limit; send now
        toSend = [row] # refresh for next round - and we know it fits!
        toSendLength = tentativeLength
    else: # otherwise, it wont be too long, so add it in
        toSend.append(row)
        toSendLength += tentative
sentToServer(json.dumps(toSend)) # if it finishes below the limit

你的解决方案的问题是,从Big-O的Angular 来看,它不是很好。我的是线性时间,你的是二次时间,因为你每次循环都要检查累积长度。每次重置postData也不是很有效。

相关问题