2012-08-13 79 views
5

我将数十万条JSON记录发布到MAX数据上传限制为1MB的服务器。我的记录可能大小不一,从几百字节到几十万。Python:限制用于发布到服务器的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) 

回答

2

我会做类似如下:

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 

的问题与您的解决方案是,它不是很大从大O的观点。我的线性时间运行,你的运行在二次时间,因为你正在检查每个循环的累积长度。每次重置postData效率都不是很高。

+1

哈!在玩耍时,我差不多完全相同的解决方案。我有一个'剩下的'列表,它会发送超出限制的大小,'toSendLength'应该是'len(json.dumps(toSend)) - len(“,”)'和'tentativeLength'应该是'len(json.dumps(row))+ len(“,”),因为每个新行都会添加一个逗号和空格。谢谢rsegal! – seaders 2012-08-13 17:25:17

+0

实际上,最重要的是,我为两个json转储添加了“separators =(',',':')”,以节省更多宝贵的数据! – seaders 2012-08-13 17:33:08

+0

很高兴为您效力!你清楚地知道Python与JSON打交道的细节。你似乎再次取得进展,也许这将有助于未来的人。超酷! – rsegal 2012-08-13 17:35:59

相关问题