GAE函数调用遇问题

79 阅读2分钟

在将应用程序上传到Google App Engine并通过浏览器进行调用后,收到错误页面。错误信息如下:

Traceback (most recent call last):
  File "/base/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 507, in __call__
    handler.get(*groups)
  File "/base/data/home/apps/bulkloader160by2/1-5.337695659246114067/new_main.py", line 59, in get
    transfer = _transfer_funds(src_key,dest_key,amt)
  File "/base/data/home/apps/bulkloader160by2/1-5.337695659246114067/new_main.py", line 24, in _transfer_funds
    return db.run_in_transaction(_tx)
  File "/base/python_lib/versions/1/google/appengine/api/datastore.py", line 1885, in RunInTransaction
    DEFAULT_TRANSACTION_RETRIES, function, *args, **kwargs)
  File "/base/python_lib/versions/1/google/appengine/api/datastore.py", line 1982, in RunInTransactionCustomRetries
    result = function(*args, **kwargs)
  File "/base/data/home/apps/bulkloader160by2/1-5.337695659246114067/new_main.py", line 11, in _tx
    account = db.get(src_key)
  File "/base/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1178, in get
    keys, multiple = datastore.NormalizeAndTypeCheckKeys(keys)
  File "/base/python_lib/versions/1/google/appengine/api/datastore.py", line 136, in NormalizeAndTypeCheckKeys
    keys, multiple = NormalizeAndTypeCheck(keys, (basestring, Entity, Key))
  File "/base/python_lib/versions/1/google/appengine/api/datastore.py", line 115, in NormalizeAndTypeCheck
    (types, arg, typename(arg)))
BadArgumentError: Expected an instance or sequence of (<type 'basestring'>, <class 'google.appengine.api.datastore.Entity'>, <class 'google.appengine.api.datastore_types.Key'>); received None (a NoneType).

main.py 文件中,通过 get 方法调用 _transfer_funds 函数,但收到错误信息。

2、解决方案

问题在于 src_keyNone。这可能是由于 GqlQuery 查询没有返回任何结果,导致 get() 方法返回 None

可以通过以下方式解决问题:

  1. 确保 GqlQuery 查询可以返回想要的结果。可以通过在查询中添加必要的过滤器或使用 fetch() 方法来获取查询结果。
  2. 在调用 db.get() 方法之前,检查 src_key 是否为 None。如果 src_keyNone,则可以抛出异常或返回默认值。

以下是修改后的代码示例:

def get(self):
    src_username = str(self.request.get('from_username'))
    dest_username = str(self.request.get('to_username'))
    amt = str(self.request.get('amount'))
    src_key = db.GqlQuery('SELECT __key__ FROM UserDetails WHERE user_name = :uname', uname = src_username).get()

    if src_key is None:
        raise Exception('No user found with username {}'.format(src_username))

    dest_key = db.GqlQuery('SELECT __key__ FROM UserDetails WHERE user_name = :uname', uname = dest_username).get()

    if dest_key is None:
        raise Exception('No user found with username {}'.format(dest_username))

    transfer = _transfer_funds(src_key, dest_key, amt)
    progress = _roll_forward(transfer)
    srcUserDetails = UserDetails.gql('WHERE user_name = :uname', uname = src_username).fetch(1)
    destUserDetails = UserDetails.gql('WHERE user_name = :uname', uname = dest_username).fetch(1)
    values = {
        'progress': progress,
        'srcUser': srcUserDetails,
        'destUser': destUserDetails
    }
    self.response.out.write(template.render('transactions.html', values))  

通过在查询中添加必要的过滤器,可以确保 GqlQuery 查询可以返回想要的结果。同时,在调用 db.get() 方法之前,检查 src_key 是否为 None,如果为 None 则抛出异常,这样可以更清晰地处理错误情况。