2016-08-29 33 views
0

我目前正在为Google Python App Engine编写一个应用程序。我想获取数据存储区中的第一条记录,但由于某种原因,这不起作用。这是我会做它在MySQL:在GAE中从NDB数据存储中获取第一条记录

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) 
+1

显示完整的回溯。但是也要注意,将数据存储视为正常数据库是错误的;订单的唯一概念由索引提供。 –

+1

我得到'ValueError:没有在[MyClass]数据存储中找到记录(我用'ValueError'替换了你未定义的'ModelException')。所以你的问题可能在别的地方。另外 - '第一个'只意味着结果列表中的第一个 - 如果你的意思是别的,你还需要提供一些排序规则。 –

+0

@DanielRoseman添加了我的堆栈跟踪 – Paradoxis

回答

1

好像你正试图立即检索数据是经过写入数据存储区,除非您在App Engine的Storing Data in Cloud Datastore文档中所述的每个实体上设置相同的parent key,否则该数据存储区将无法工作。

要创建parent key,你可以写:

from google.appengine.ext.ndb import Key 
parent_key = Key('my_data', 'version_1') 

,当你创建你的实体,你应该通过parent keyconstructor

my_entity = MyKindClass(parent=parent_key, foo=foo_input, bar=bar_input) 

然后,通过传递查询数据库您的kind类别的parent_keyquery方法:

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的The Python NDB Client Library Overview文件。

相关问题