2016-08-29 34 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文件。

相關問題