谷歌应用引擎NDB数据库损坏?

2024-04-25 07:33:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我经常会遇到一些随机错误,比如:

suspended generator _get_tasklet(context.py:329) raised ProtocolBufferDecodeError(corrupted)

或者

^{pr2}$

或者

suspended generator put(context.py:796) raised ValueError(Invalid \escape: line 1 column 18002 (char 18002))

或者

suspended generator _get_tasklet(context.py:329) raised ProtocolBufferDecodeError(truncated)

几天前一切都很好,我还没有做任何改变。当我重新启动我的应用程序时,大约5分钟内一切正常,直到我得到

suspended generator _get_tasklet(context.py:329) raised ProtocolBufferDecodeError(corrupted)

在这之后,每个数据库put或get上都会出现一个其他错误。导致错误的表和代码每次都不同。我不知道从哪里开始,因为错误每次都在一个新的地方。 这些只是常规的数据库put和get,比如

ndbstate = NdbStateJ.get_by_id(self.screen_name)

或者

ndbstate.put()

谷歌搜索无法给我指明任何特定的方向。有什么想法吗? 错误

Expecting , delimiter: line 1 column 440 (char 440)

可能是因为某些表中的某些字段类型是JSON。但为什么突然?在

所以也许我没有在某个地方正确地转义,比如使用r'{…}',但是如果某个地方有一个错误的条目,如果我不能查询,该如何修复它?为什么它会破坏所有查询的整个表?为什么是随机的。每次都不一样。在

下面是一个表格的例子

class NdbStateJ(ndb.Model):
    last_id = ndb.IntegerProperty()
    last_search_id = ndb.IntegerProperty()
    last_geo_id = ndb.IntegerProperty()
    mytweet_num = ndb.IntegerProperty()
    mentions_processed = ndb.JsonProperty()
    previous_follower_responses = ndb.JsonProperty()
    my_tweets_tweeted = ndb.JsonProperty()
    responses_already_used = ndb.JsonProperty()
    num_followed_by_cyborg = ndb.IntegerProperty(default=0)
    num_did_not_follow_back = ndb.IntegerProperty(default=0)
    language_model_vector = ndb.FloatProperty(repeated=True)
    follow_wait_counter = ndb.IntegerProperty(default=0)

下面是一个创建表的示例

ndbstate = NdbStateJ(id=screen_name,
last_id = 37397357946732541,
last_geo_id = 37397357946732541,
last_search_id = 0,
mytweet_num = 0,
mentions_processed = [],
previous_follower_responses = [],
my_tweets_tweeted = [],
responses_already_used= [],
language_model_vector = [])
ndbstate.put()

Tags: pyidgetput错误contextgeneratornum
1条回答
网友
1楼 · 发布于 2024-04-25 07:33:46

JSON数据库格式不正确,导致问题。我不知道为什么突然间这个问题开始在所有地方发生;也许谷歌方面发生了一些变化,或者我没有充分检查,新用户能够输入格式错误的数据。谁知道呢。在

为了解决这个问题,我从https://stackoverflow.com/users/1011633/nizz响应App Engine return JSON from JsonPropertyhttps://stackoverflow.com/users/1709587/mark-amery响应How to escape special characters in building a JSON string?、以及{a5}响应How do I automatically fix an invalid JSON string?中获得灵感。在

我将ndb.JsonProperty()替换为ExtendedJsonProperty,其中扩展版本与下面的代码类似。在

import json
from google.appengine.ext import ndb 
import logging
logging.getLogger().setLevel(logging.DEBUG)
import re

class ExtendedJsonProperty(ndb.BlobProperty):
    # Inspired by https://stackoverflow.com/questions/18576556/app-engine-return-json-from-jsonproperty
    def _to_base_type(self, value):
        logging.debug('Dumping value '+str(value))
        try:
            return json.dumps(value) 
        except Exception as e:
            logging.warning(('trying to fix error dumping from database: ') +str(e))
            return fix_json(value,json.dumps)

    def _from_base_type(self, value):
        # originally return json.loads(value)
        logging.debug('Loading value '+str(value))
        try:
            return json.loads(value)
        except Exception as e:
            logging.warning(('trying to fix error loading from database: ') +str(e))
            return fix_json(value,json.loads)        

def fix_json(s,json_fun):
    for _i in range(len(s)):
        try:
            result = json_fun(s)   # try to parse...
            return result                    
        except Exception as e:  
            logging.debug('Exception for json loads: '+str(e))          
            if 'delimiter' in str(e):
                # E.g.: "Expecting , delimiter: line 34 column 54 (char 1158)"
                logging.debug('Escaping quote to fix.')
                s = escape_quote(s,e)
            elif 'escape' in str(e):
                # E.g.: "Invalid \escape: line 1 column 9 (char 9)"
                logging.debug('Removing invalid escape to fix.')
                s = remove_invalid_escape(s)
            else:
                break
    return json_fun('{}')

def remove_invalid_escape(value):
    # Inspired by https://stackoverflow.com/questions/19176024/how-to-escape-special-characters-in-building-a-json-string
    return re.sub(r'\\(?!["\\/bfnrt])', '', value)

def escape_quote(s,e):
    # Inspired by https://stackoverflow.com/questions/18514910/how-do-i-automatically-fix-an-invalid-json-string
    # "Expecting , delimiter: line 34 column 54 (char 1158)"
    # position of unexpected character after '"'
    unexp = int(re.findall(r'\(char (\d+)\)', str(e))[0])
    # position of unescaped '"' before that
    unesc = s.rfind(r'"', 0, unexp)
    s = s[:unesc] + r'\"' + s[unesc+1:]
    # position of corresponding closing '"' (+2 for inserted '\')
    closg = s.find(r'"', unesc + 2)
    if closg + 2 < len(s):
        print closg, len(s)
        s = s[:closg] + r'\"' + s[closg+1:]
    return s

相关问题 更多 >

    热门问题