2016-08-29 4 views
0

В настоящее время я пишу приложение в Google App Engine для Python. Я хочу получить первую запись в моем хранилище данных, но по какой-то причине это не сработает. Это, как я хотел бы сделать это в MySQL:Получение первой записи из хранилища данных NDB в GAE

SELECT * FROM MyClass LIMIT 1; 

Однако, так как я новичок в ОПРС, я не могу совсем, кажется, обернуть вокруг головы, как это работает. Я попробовал прочитать примеры 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] datastore' (я заменил ваше неопределенное' ModelException' на 'ValueError'). Поэтому ваша проблема может лежать где-то в другом месте. Кроме того, 'first' будет означать только первое в списке результатов - если вы имеете в виду что-то еще, вам нужно будет также предоставить некоторое правило сортировки. –

+0

@ DanielRoseman добавил мою трассировку следа – Paradoxis

ответ

1

Похоже, вы пытаетесь немедленно восстановить данные после того, как она записанный в хранилище данных, которое не будет работать, если вы не установите тот же parent key для каждого объекта, как указано в документе Storing Data in Cloud Datastore в App Engine.

Чтобы создать 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) 

Для получения дополнительной информации см The Python NDB Client Library Overview документа App Engine.

Смежные вопросы