我目前正在使用Google App Engine for Python编写应用程序。我想获取我的数据存储区中的第一条记录,但由于某种原因,这将无法正常工作。这就是我在MySQL中的表现:
SELECT * FROM MyClass LIMIT 1;
然而,由于我是NDB的新手,我似乎无法理解这是如何运作的。我尝试阅读the documentation作为示例,但它们并不常用。
这是我目前的代码:
from google.appengine.ext.ndb import Model as NdbModel
from google.appengine.ext.ndb import StringProperty
class Model(NdbModel):
@classmethod
def get_first(cls):
"""
Get the first record in the model datastore
:return: Model
"""
try:
return cls.query().fetch(1)[0]
except IndexError:
raise ModelException("No records found in [%s] datastore" % cls.__name__)
class MyClass(Model):
foo = StringProperty()
bar = StringProperty()
a = MyClass.get_first() # TypeError: 'NoneType' object does not support item assignment
这是我的完整堆栈跟踪:
TypeError: 'NoneType' object does not support item assignment
at _store_value (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py:1127)
at _deserialize (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py:1496)
at _from_pb (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py:3209)
at pb_to_entity (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py:691)
at pb_to_query_result (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/datastore/datastore_rpc.py:201)
at _process_results (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/datastore/datastore_query.py:2980)
at __query_result_hook (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/datastore/datastore_query.py:2947)
at get_result (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/apiproxy_stub_map.py:613)
at _on_rpc_completion (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py:513)
at _run_to_list (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py:995)
at _help_tasklet_along (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py:427)
at get_result (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py:383)
at fetch (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py:1218)
at positional_wrapper (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/utils.py:160)
at get_first (/base/data/home/apps/s~project-id/v1.395271489319521947/project/core/models/utils.py:55)
at me (/base/data/home/apps/s~project-id/v1.395271489319521947/project/core/routes/api/v1/profile.py:22)
at dispatch_request (/base/data/home/apps/s~project-id/v1.395271489319521947/lib/flask/app.py:1625)
at full_dispatch_request (/base/data/home/apps/s~project-id/v1.395271489319521947/lib/flask/app.py:1639)
at handle_user_exception (/base/data/home/apps/s~project-id/v1.395271489319521947/lib/flask/app.py:1544)
at full_dispatch_request (/base/data/home/apps/s~project-id/v1.395271489319521947/lib/flask/app.py:1641)
at wsgi_app (/base/data/home/apps/s~project-id/v1.395271489319521947/lib/flask/app.py:1988)
at handle_exception (/base/data/home/apps/s~project-id/v1.395271489319521947/lib/flask/app.py:1567)
at wsgi_app (/base/data/home/apps/s~project-id/v1.395271489319521947/lib/flask/app.py:1991)
at __call__ (/base/data/home/apps/s~project-id/v1.395271489319521947/lib/flask/app.py:2000)
at Handle (/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py:267)
答案 0 :(得分:1)
在您将数据写入数据存储区之后,您似乎正在尝试立即检索数据,除非您按照App Engine {{3}中的说明在每个实体上设置相同的parent key
,否则这将无法正常工作文件。
要创建parent key
,您可以写:
from google.appengine.ext.ndb import Key
parent_key = Key('my_data', 'version_1')
当您创建实体时,应将parent key
传递给constructor
:
my_entity = MyKindClass(parent=parent_key, foo=foo_input, bar=bar_input)
然后,通过将parent_key
类的query
传递给kind
方法来查询数据库:
first_result = MyKindClass.query(
ancestor=parent_key).order(-MyKindClass.created).get()
我认为您对获取最新数据感兴趣,因此我使用order
方法使用-
运算符对结果进行了排序,该运算符对数据进行了降序排序。另外,我使用get
方法而不是fetch(1)
,如果没有数据,则返回第一个查询结果或None
。
完整的代码将是:
import webapp2
from google.appengine.ext.ndb import (
Model, StringProperty, DateTimeProperty, Key)
class MyKindClass(Model):
foo = StringProperty()
bar = StringProperty()
created = DateTimeProperty(auto_now_add=True)
parent_key = Key('my_data', 'version_1')
class MainHandler(webapp2.RequestHandler):
def get(self):
foo_input = self.request.get('foo')
bar_input = self.request.get('bar')
if foo_input and bar_input:
my_entity = MyKindClass(parent=parent_key,
foo=foo_input, bar=bar_input)
my_entity.put()
first_result = MyKindClass.query(
ancestor=parent_key).order(-MyKindClass.created).get()
if first_result is not None:
self.response.write('foo: %s, and bar: %s' %
(first_result.foo, first_result.bar))
else:
self.response.write('No data yet!')
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
有关详细信息,请参阅App Engine的Storing Data in Cloud Datastore文档。