Google App Engine - BadArgumentError - 不明白为什么

时间:2015-05-01 08:51:39

标签: python google-app-engine gql

我的GAE应用程序中出现BadArgumentError,我无法弄清楚原因。

我有一个实体模型,我实际上将其用作不同实体之间的连接表。我有一些遗留代码遍历此实体的所有实例以检查(并填充)任何已知的漏洞。我已经慢慢摆脱它,因为我验证我已经有其他错误检查程序,但无法解决这个问题。 (如果你通过逻辑思考它在这一点上基本上什么都不做,如果不是这个错误,我会把它全部删除。)

检查/填充已知孔(缺少ReferenceProperties)的代码被设置为任务队列。主处理程序将key()。id()作为参数发送给worker,然后查找实例,检查它是否有ReferenceProperty,如果没有则删除它。

奇怪的是,日志记录显示一个Entity实例,但是当我尝试删除它时,我得到一个BadArgumentError。此外,当我在App Engine数据存储查看器上查找

(SELECT * FROM InvestorRoundPair where __key__ = KEY('InvestorRoundPair', 5701213970497536))

它不会返回任何结果。

所以看起来实际上没有实体存在的实体实例......但不知何故,处理程序仍能找到它并将其发送给工作者?

就像我在App Engine中所做的那样,我仍然是一个非常业余的人,可能会错过一些非常明显的东西。但也许不是吗?我真的很喜欢帮助理解正在发生的事情以及我应该做些什么(如果有的话)来修复它。

models.py

class InvestorRoundPair(db.Model):
    investor = db.ReferenceProperty(SeedInvestor, collection_name = 'investorgroup')
    funding_round = db.ReferenceProperty(FundingRound, collection_name = 'fundingroundgroup')
    accelerator_entry = db.ReferenceProperty(SeedAccelerator, collection_name = 'acceleratorgroup')
    company_entry = db.ReferenceProperty(SeedCompany, collection_name = 'companygroup')

类/方法

class FillHolesHandler(handlers.BaseRequestHandler):
    def get(self):
        listofholes = InvestorRoundPair.all().order('-funding_round')
        for entry in listofholes:
            objid = entry.key().id()
            taskqueue.add(url='/investorgraph/graphholefiller', params={'objid': objid}, queue_name='holefiller')

class GraphHoleFillerWorker(handlers.BaseRequestHandler):
    def post(self):
        objid = self.request.get('objid')
        entry = InvestorRoundPair.get_by_id(int(objid))
        logging.info('InvestorRoundPair %s', objid)
        try:
            fundingroundkey = entry.funding_round.key().id()
        except AttributeError:
            db.delete(entry)

错误

InvestorRoundPair 5701213970497536
[...]
File "/base/data/home/apps/s~seed-db/1.383964211518800837/investorgraph.py", line 132, in post
    db.delete(entry)
[...]
BadArgumentError: Expected one of (<type 'basestring'>, <class 'google.appengine.api.datastore.Entity'>, <class 'google.appengine.api.datastore_types.Key'>); received None (a NoneType).

1 个答案:

答案 0 :(得分:1)

我怀疑问题是你的代码不是幂等的。 App Engine不保证任何特定任务只执行一次。因此,您的任务可以运行,删除实体,然后再次运行并且无法找到它。

在尝试访问其属性或删除属性之前,您应该只检查get_by_id是否有效且entry不是无。