天道酬勤,学无止境

How to fetch the latest data in GAE Python NDB

I am using GAE Python. I have two root entities:

class X(ndb.Model):  
    subject = ndb.StringProperty()  
    grade = ndb.StringProperty()  

class Y(ndb.Model):  
    identifier = ndb.StringProperty()  
    name = ndb.StringProperty()  
    school = ndb.StringProperty()  
    year = ndb.StringProperty()  
    result = ndb.StructuredProperty(X, repeated=True)  

Since google stores our data across several data centers, we might not get the most recent data when we do a query as shown below(in case some changes have been "put"):

def post(self):  
    identifier = self.request.get('identifier')  
    name = self.request.get('name')  
    school = self.request.get('school')  
    year = self.request.get('year')  
    qry = Y.query(ndb.AND(Y.name==name, Y.school==school, Y.year==year))  
    record_list = qry.fetch()  

My question: How should I modify the above fetch operation to always get the latest data

I have gone through the related google help doc but could not understand how to apply that here

Based on hints from Isaac answer, Would the following be the solution(would "latest_record_data" contain the latest data of the entity):

def post(self):  
    identifier = self.request.get('identifier')  
    name = self.request.get('name')  
    school = self.request.get('school')  
    year = self.request.get('year')  
    qry = Y.query(ndb.AND(Y.name==name, Y.school==school, Y.year==year))  
    record_list = qry.fetch()  
    record = record_list[0]  
    latest_record_data = record.key.get()  

评论

There's a couple ways on app engine to get strong consistency, most commonly using gets instead of queries and using ancestor queries.

To use a get in your example, you could encode the name into the entity key:

class Y(ndb.Model):
  result = ndb.StructuredProperty(X, repeated=True)

def put(name, result):
  Y(key=ndb.Key(Y, name), result).put()

def get_records(name):
  record_list = ndb.Key(Y, name).get()
  return record_list

An ancestor query uses similar concepts to do something more powerful. For example, fetching the latest record with a specific name:

import time

class Y(ndb.Model):
  result = ndb.StructuredProperty(X, repeated=True)

  @classmethod
  def put_result(cls, name, result):
    # Don't use integers for last field in key. (one weird trick)
    key = ndb.Key('name', name, cls, str(int(time.time())))
    cls(key=key, result=result).put()

  @classmethod
  def get_latest_result(cls, name):
    qry = cls.query(ancestor=ndb.Key('name', name)).order(-cls.key)
    latest = qry.fetch(1)
    if latest:
      return latest[0]

The "ancestor" is the first pair of the entity's key. As long as you can put a key with at least the first pair into the query, you'll get strong consistency.

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Google ndb库中的内存泄漏(Memory leak in Google ndb library)
    问题 我认为ndb库中存在内存泄漏,但是我找不到位置。 有没有一种方法可以避免以下所述的问题? 您是否有一个更准确的测试思路来找出问题所在? 这就是我重现问题的方式: 我用2个文件创建了一个简约的Google App Engine应用程序。 app.yaml : application: myapplicationid version: demo runtime: python27 api_version: 1 threadsafe: yes handlers: - url: /.* script: main.APP libraries: - name: webapp2 version: latest main.py : # -*- coding: utf-8 -*- """Memory leak demo.""" from google.appengine.ext import ndb import webapp2 class DummyModel(ndb.Model): content = ndb.TextProperty() class CreatePage(webapp2.RequestHandler): def get(self): value = str(102**100000) entities = (DummyModel(content=value) for _
  • GAE Python:静态文件未在本地主机中加载,但是在将应用程序部署到appspot时加载完全正常(GAE Python: Static Files not loading in localhost, but load perfectly fine when app is deployed onto appspot)
    问题 我遇到一个奇怪的问题,正在寻找解决方案,但到目前为止,它似乎很独特。 我的问题是,当我在GAE中使用localhost运行应用程序时,无法加载我的静态文件(css,模板,javascript等)。 但是,当我将应用程序部署到GAE服务器(appspot)上时,这些静态文件运行得非常好! 对于在GAE文档中找到的默认Guestbook应用程序,甚至会发生这种情况。 我在Windows上使用GAE启动器(Python)1.9.6。 Python是64位版本2.7.7。 已经确保GAE指向python的正确位置。 到目前为止,每个应用程序都遇到此问题,因此我怀疑这是代码问题。 但是,以下代码供您参考: app.yaml application: ipeech version: 1 runtime: python27 api_version: 1 threadsafe: true handlers: - url: /stylesheets static_dir: stylesheets - url: /.* script: guestbook.application libraries: - name: webapp2 version: latest - name: jinja2 version: latest guestbook.py import os import urllib
  • GAE Python: Static Files not loading in localhost, but load perfectly fine when app is deployed onto appspot
    I'm experiencing a weird problem, searched for a solution but so far, it appears unique. My problem is, my static files (css, templates, javascript, etc) do not load when I run the app using localhost in GAE. However, when I deploy the app onto GAE servers (appspot), these static files run perfectly fine! This even occurs for the default Guestbook app found in the GAE documentation. I'm using GAE launcher (Python) 1.9.6 on Windows. Python is the 64 bit version, 2.7.7. Already made sure GAE is pointing to the right location for python. I'm experiencing this problem with every app so far, so I
  • 从数据存储区查询大量ndb实体的最佳实践(Best practice to query large number of ndb entities from datastore)
    问题 App Engine数据存储区遇到了一个有趣的限制。 我正在创建一个处理程序,以帮助我们分析其中一台生产服务器上的一些使用情况数据。 要执行分析,我需要查询和汇总从数据存储中提取的10,000多个实体。 计算并不难,它只是通过使用率样本的特定过滤器的项目的直方图。 我遇到的问题是,在达到查询截止日期之前,我无法足够快地从数据存储中取回数据以进行任何处理。 我已经尝试了所有可以想到的将查询分块为并行RPC调用以提高性能的方法,但是根据appstats的说法,我似乎无法使查询实际并行执行。 不管我尝试哪种方法(请参见下文),似乎RPC总是回落到顺序的下一个查询的瀑布上。 注意:查询和分析代码确实有效,但运行速度很慢,因为我无法从数据存储中足够快地获取数据。 背景 我没有可以共享的实时版本,但是这里是我所讨论的系统部分的基本模型: class Session(ndb.Model): """ A tracked user session. (customer account (company), version, OS, etc) """ data = ndb.JsonProperty(required = False, indexed = False) class Sample(ndb.Model): name = ndb.StringProperty (required =
  • 如何在Google App Engine(Python)中使用AJAX(How to use AJAX with Google App Engine (Python))
    问题 我完全是AJAX的新手。 我熟悉HTML / CSS,jQuery和GAE和Python的初学者。 为了理解AJAX的工作原理,我想知道如何在下面的示例中使用AJAX(实际代码)。 让我们使用类似于reddit的示例,其中上下左右投票的方式被取消: 这是故事种类: class Story(ndb.Model): title = ndb.StringProperty(required = True) vote_count = ndb.IntegerProperty(default = 0) HTML看起来像这样: <h2>{{story.title}}</h2> <div> {{story.vote_count}} | <a href="#">Vote Up Story</a> </div> AJAX如何容纳在这里? 回答1 好吧,先生,我们走了...一个带有一个故事和无限投票的简单应用... ;-) app.yaml application: anotherappname version: 1 runtime: python27 api_version: 1 threadsafe: true default_expiration: "0d 0h 5m" libraries: - name: jinja2 version: latest - name: webapp2
  • 提高 ndb 查询大数据的吞吐量(Improve throughput of ndb query over large data)
    问题 我正在尝试在 GAE 应用程序中对存储在数据存储中的数据执行一些数据处理。 瓶颈点是查询返回实体的吞吐量,我想知道如何提高查询的性能。 我一般做什么: 一切都在任务队列中工作,所以我们有足够的时间(10 分钟截止日期)。 我对 ndb 实体运行查询以选择需要处理的实体。 当查询返回结果时,我将实体按批次分组,例如 1000 个,并将它们发送到另一个任务队列进行进一步处理。 存储的数据将会很大(比如 500K-1M 实体),并且 10 分钟的截止日期可能不够。 因此,当任务到达任务队列截止日期时,我会生成一个新任务。 这意味着我需要一个 ndb.Cursor 才能从停止的地方继续查询。 问题是查询返回实体的速率。 我尝试了几种方法并观察到以下性能(这对我的应用程序来说太慢了): 在 while 循环中使用 fetch_page()。 代码很简单 while has_more and theres_more_time: entities, cursor, more = query.fetch_page(1000, ...) send_to_process_queue(entities) has_more = more and cursor 使用这种方法,处理 10K 个实体需要 25-30 秒。 粗略地说,即每分钟 20K 个实体。 我尝试更改页面大小或前端实例的类;
  • GAE ndb的设计,性能和重复属性的使用(GAE ndb design, performance and use of repeated properties)
    问题 假设我有一个图片库,而一张图片可能有10万多名粉丝。 哪种NDB设计更有效? class picture(ndb.model): fanIds = ndb.StringProperty(repeated=True) ... [other picture properties] 或者 class picture(ndb.model): ... [other picture properties] class fan(ndb.model): pictureId = StringProperty() fanId = StringProperty() 可以添加到ndb重复属性中的项目数是否有限制,并且在重复属性中存储大量项目是否会对性能造成影响? 如果使用重复属性的效率较低,那么它们的预期用途是什么? 回答1 如果您使用的属性值超过100-1000,则不要使用重复属性。 (可能已经在推动它了1000。)它们不是设计用于这种用途的。 回答2 通常v1会便宜得多。 就读/写成本而言,您需要为获取/写入的每个实体付费,因此您希望减少实体的数量。 版本1会便宜一些。 如果您每次获取图片都获取每个风扇,则价格会便宜很多。 但是,每个实体限制为1MB。 如果您有超过100k的粉丝,则可以根据fanId的大小达到该限制。 那不算您的其他图片数据,因此您可能会超出1MB的限制。
  • 如何删除Google App Engine中的所有数据存储区?(How to delete all datastore in Google App Engine?)
    问题 有人知道如何删除Google App Engine中的所有数据存储吗? 回答1 如果您正在谈论实时数据存储,请打开应用程序的仪表板(在appengine上登录),然后打开数据存储-> dataviewer,选择要删除的表的所有行,然后单击Delete按钮(您必须为您的所有表格执行此操作)。 您可以通过remote_api以编程方式进行相同操作(但我从未使用过)。 如果您在谈论开发数据存储,则只需删除以下文件: “ ./WEB-INF/appengine-generation/local_db.bin” 。 下次您运行开发服务器时,将再次为您生成该文件,并且您将获得一个清晰的数据库。 确保随后清理您的项目。 这是开始使用Google Application Engine时会派上用场的小陷阱之一。 您会发现自己将对象持久化到数据存储中,然后为持久性实体更改JDO对象模型,最终导致过时的数据使应用程序崩溃。 回答2 最好的方法是Nick所建议的远程API方法,他是Google的App Engine工程师,所以请相信他。 这并不难,最新的1.2.5 SDK提供了现成的remote_shell_api.py。 因此,请下载新的SDK。 然后按照下列步骤操作: 在您的命令行中连接远程服务器: remote_shell_api.py yourapp /remote
  • Improve throughput of ndb query over large data
    I am trying to perform some data processing in a GAE application over data that is stored in the Datastore. The bottleneck point is the throughput in which the query returns entities and I wonder how to improve the query's performance. What I do in general: everything works in a task queue, so we have plenty of time (10 minute deadline). I run a query over the ndb entities in order to select which entities need to be processed. as the query returns results, I group entities in batches of, say, 1000 and send them to another task queue for further processing. the stored data is going to be large
  • Securely storing environment variables in GAE with app.yaml(Securely storing environment variables in GAE with app.yaml)
    问题 我需要将API密钥和其他敏感信息作为环境变量存储在app.yaml ,以便在GAE上进行部署。 问题是,如果我将app.yaml推送到GitHub,此信息将变为公开(不好)。 我不想将信息存储在数据存储中,因为它不适合该项目。 而是,我希望在应用程序的每次部署中从.gitignore列出的文件中换出值。 这是我的app.yaml文件: application: myapp version: 3 runtime: python27 api_version: 1 threadsafe: true libraries: - name: webapp2 version: latest - name: jinja2 version: latest handlers: - url: /static static_dir: static - url: /.* script: main.application login: required secure: always # auth_fail_action: unauthorized env_variables: CLIENT_ID: ${CLIENT_ID} CLIENT_SECRET: ${CLIENT_SECRET} ORG: ${ORG} ACCESS_TOKEN: ${ACCESS_TOKEN} SESSION_SECRET: $
  • Google App Engine NDB:如何存储文档结构?(Google App Engine NDB: How to store document structure?)
    问题 来自 App Engine NDB 文档: NDB API 在无模式对象数据存储中提供持久存储。 它支持自动缓存、复杂查询和原子事务。 NDB 非常适合存储结构化数据记录。 我想使用 NDB 创建如下结构,其中每个实例如下所示: { city: 'SFO' date: '2013-01-27' data: { 'keyword1': count1, 'keyword2': count2, 'keyword3': count3, 'keyword4': count4, 'keyword5': count5, .... } } 如何使用 NDB 在 Google App Engine(GAE) 中设计这样一个无模式实体? 我是 GAE 的新手,不知道如何实现这一目标 谢谢 回答1 如果您不需要查询数据中的属性,您可以使用@voscausa 提到的属性之一: 属性 class MyModel(ndb.Model): city = ndb.StringProperty() date = ndb.DateProperty() data = ndb.JsonProperty() my_model = MyModel(city="somewhere", date=datetime.date.today(), data={'keyword1': 3, 'keyword2': 5,
  • What is the correct way to get the previous page of results given an NDB cursor?
    I'm working on providing an API via GAE that will allow users to page forwards and backwards through a set of entities. I've reviewed the section about cursors on the NDB Queries documentation page, which includes some sample code that describes how to page backwards through query results, but it doesn't seem to be working as desired. I'm using GAE Development SDK 1.8.8. Here's a modified version of that example that creates 5 sample entities, gets and prints the first page, steps forward into and prints the second page, and attempts to step backwards and print the first page again: import
  • google app引擎ndb:put()然后query(),总是少一个(google app engine ndb: put() and then query(), there is always one less item)
    问题 我想知道是否有人在Google App Engine的NDB上遇到了奇怪的问题:创建新实体并通过put()保存它之后; 然后立即执行query() ,总是少一件商品。 例如, class Item(ndb.Model): ... ... items = Item.query().fetch() length1 = len(items) item = Item() item.put() items = Item.query().fetch() length2 = len(items) 在上文中, length1总是等于length2 。 但是, length2重新访问同一HTML页面时, length2将被更正。 问题是什么? 谢谢。 回答1 我通过进行适当的查询,创建新的模型记录,然后将其附加到查询中,然后再返回来解决了这一问题。 修改您的内容,如下所示: class Item(ndb.Model): ... ... items = Item.query().fetch() length1 = len(items) item = Item() item.put() appended_items = list() for existing_item in items: appended_items.append(existing_item) appended_items
  • 给定NDB游标,获取上一页结果的正确方法是什么?(What is the correct way to get the previous page of results given an NDB cursor?)
    问题 我正在通过GAE提供一种API,该API将允许用户通过一组实体向前和向后翻页。 我已经查看了NDB Queries文档页面上有关游标的部分,其中包括一些示例代码,这些代码描述了如何通过查询结果向后翻页,但是似乎无法正常工作。 我正在使用GAE开发SDK 1.8.8。 这是该示例的修改版本,该示例创建5个示例实体,获取并打印第一页,前进并打印第二页,然后尝试向后退一步并再次打印第一页: import pprint from google.appengine.ext import ndb class Bar(ndb.Model): foo = ndb.StringProperty() #ndb.put_multi([Bar(foo="a"), Bar(foo="b"), Bar(foo="c"), Bar(foo="d"), Bar(foo="e")]) # Set up. q = Bar.query() q_forward = q.order(Bar.foo) q_reverse = q.order(-Bar.foo) # Fetch the first page. bars1, cursor1, more1 = q_forward.fetch_page(2) pprint.pprint(bars1) # Fetch the next (2nd) page. bars2
  • Google App Engine + Python 中的 REST API?(REST API in Google App Engine + Python?)
    问题 如何使用 Google App Engine 和 Python 创建 RESTful API? 我曾尝试使用 Cloud Endpoints,但文档并未关注 RESTful API。 是否有类似于 GAE 的 django-tastypie 的东西? 回答1 RESTful api 可以基于 EndPoint API 构建。 有一些工具可以帮助您简化操作: appengine 休息服务器(不基于端点) Google App Engine 应用程序的嵌入式服务器,无需额外工作即可通过 REST API 公开您的数据模型。 https://code.google.com/p/appengine-rest-server/ 另一种是基于端点 通过扩展 ndb.Model 类和端点库提供的功能,该库允许您直接与 API 方法中的模型实体交互,而不是 ProtoRPC 请求。 例如,而不是: https://github.com/GoogleCloudPlatform/endpoints-proto-datastore 编辑1: 我为端点编写了一个 RESTFul api 生成器。 # generate restful api in one line BigDataLab = EndpointRestBuilder(GPCode).build( api_name="BigDataLab"
  • GAE: AssertionError: No api proxy found for service “datastore_v3”
    I'm writing simple to code to access dev server. Both dev server and datastore emulated have been started locally. from google.appengine.ext import ndb class Account(ndb.Model): name = ndb.StringProperty() acc = Account(name=u"test").put() print(acc) Error: AssertionError: No api proxy found for service "datastore_v3" I tried to set: export DATASTORE_EMULATOR_HOST=localhost:8760 . It does not help. $ dev_appserver.py ./app.yaml WARNING 2017-02-20 06:40:23,130 application_configuration.py:176] The "python" runtime specified in "./app.yaml" is not supported - the "python27" runtime will be used
  • GAE: Enabling Edge Cache with webapp2 (Python)
    There has been this new video on youtube demonstrating the strength of EdgeCaching in the GAE architecture, and at this particular point in the video they demonstrate how easy it is to leverage: http://www.youtube.com/watch?v=QJp6hmASstQ#t=11m12 Unfortunately it's not that easy... I'm looking to enable edge caching using the webapp2 framework provided by Google. I'm calling: self.response.pragma = 'Public' self.response.cache_expires(300) but it seems overridden by something else. The header I get is: HTTP/1.1 200 OK Pragma: Public Cache-Control: max-age=300, no-cache Expires: Sat, 23 Feb 2013
  • 查询GAE数据存储时如何解决索引错误?(How to fix index error when querying GAE datastore?)
    问题 当我尝试在按日期排序的数据存储上运行查询时,出现以下错误: NeedIndexError: no matching index found. The suggested index for this query is: - kind: Message properties: - name: author - name: ref - name: date 如果我不尝试按日期排序,查询将无错误运行。 数据存储区索引下的appengine控制台说: author ▲ , ref ▲ , date ▼ Serving 我究竟做错了什么? 如何运行按日期排序的查询? 谢谢! 这是我的实体定义: from google.appengine.ext import ndb class Message(ndb.Model): subject = ndb.StringProperty() body = ndb.TextProperty() date = ndb.DateTimeProperty(auto_now_add=True) ref = ndb.StringProperty( required=True ) author = ndb.KeyProperty(required=True) 这是失败的查询: def readMessages( ref, user = None ): query
  • Google App Engine (Python) - 上传文件(图片)(Google App Engine (Python) - Uploading a file (image))
    问题 我希望用户能够将图像上传到 Google App Engine。 我有以下(Python): class ImageData(ndb.Model): name = ndb.StringProperty(indexed=False) image = ndb.BlobProperty() 用户使用表单 (HTML) 提交信息: <form name = "input" action = "/register" method = "post"> name: <input type = "text" name = "name"> image: <input type = "file" name = "image"> </form> 然后通过以下方式处理: class AddProduct(webapp2.RequestHandler): def post(self): imagedata = ImageData(parent=image_key(image_name)) imagedata.name = self.request.get('name') imagedata.image = self.request.get('image') imagedata.put() 但是,当我尝试上传图像时,比如说“Book.png”,我收到错误消息: BadValueError
  • Google App Engine NDB: How to store document structure?
    From App Engine NDB documentation: The NDB API provides persistent storage in a schemaless object datastore. It supports automatic caching, sophisticated queries, and atomic transactions. NDB is well-suited to storing structured data records. I want to create a structure like the following using NDB, where each instance looks like : { city: 'SFO' date: '2013-01-27' data: { 'keyword1': count1, 'keyword2': count2, 'keyword3': count3, 'keyword4': count4, 'keyword5': count5, .... } } How can I design such a schema-less entity in Google App Engine(GAE) using NDB? I am new to GAE and not sure how to