我在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 = True, indexed = True)
session = ndb.KeyProperty (required = True, kind = Session)
timestamp = ndb.DateTimeProperty(required = True, indexed = True)
tags = ndb.StringProperty (repeated = True, indexed = True)
Run Code Online (Sandbox Code Playgroud)
您可以将样本视为用户使用给定名称功能的时间.(例如:'systemA.feature_x').标签基于客户详细信息,系统信息和功能.例如:['winxp','2.5.1','systemA','feature_x','premium_account']).因此,标签形成一组非规范化的标记,可用于查找感兴趣的样本.
我试图做的分析包括获取一个日期范围,并询问每个客户帐户(公司,而不是每个用户)每天(或每小时)使用的功能集(可能是所有功能)的特征次数.
因此处理程序的输入类似于:
输出将是:
[{
'company_account': <string>,
'counts': [
{'timeperiod': <iso8601 date>, …
Run Code Online (Sandbox Code Playgroud) 当我用ndb的方法创建一个对象时,它会自动创建Key类型(kind,id),其中id是一个数字.在整个文档中,它显示您可以使用字符串作为密钥的id,但是在创建对象时我无法找到如何自动执行此操作.
我有一个用户模型,我正在考虑使用用户的用户名(因为它的唯一)作为密钥的ID,以便更快地检索.这是一个好主意吗?我是否会对用户名有任何问题,因为它是用户提交的(我正在验证输入)?
随着最近发布的NDB,有没有理由继续使用旧的数据存储区API?
我正在开发一个当前使用旧数据存储区API的应用程序,我已经花了很多精力来缓存memcache中的对象.我的理解是正确的,通过更改为NDB,我可以删除自定义缓存,并保持当前的性能吗?
此外,NDB是否会以任何方式改变对分片计数器的需求?NDB中以某种方式更改了实体(组)每秒5次写入的限制吗?
编辑
鉴于我的应用程序仍在开发中,并且我没有我无法轻易删除的实体,在更改为NDB之前是否应该考虑一些问题,还是只需更改db.Model
为ndb.Model
?
我有一个ndb模型类:
class Game(ndb.Model):
gameID = ndb.IntegerProperty()
gameName = ndb.StringProperty()
Run Code Online (Sandbox Code Playgroud)
有没有办法快速删除存储在数据库中的所有实体?就像是Game.deletAll()
我正在创建一个Google App Engine应用程序(python),我正在学习一般框架.我一直在查看NDB数据存储区的教程和文档,我在概念上遇到了一些困难.我有一个很大的SQL数据库背景,我从来没有使用任何其他类型的数据存储系统,所以我认为这是我遇到麻烦的地方.
我目前的理解是:NDB数据存储区是具有属性(类似于DB字段/列)的实体(类似于DB记录)的集合.使用模型(类似于DB模式)创建实体.每个实体都有一个存储时为其生成的密钥.这是我遇到麻烦的地方,因为这些密钥似乎与SQL DB概念中的任何东西都没有类比.它们看起来类似于表的主键,但它们更紧密地绑定到记录,实际上它们是字段本身.这些NDB密钥不是实体的属性,但被视为与实体分离的对象.如果实体存储在数据存储区中,则可以使用其密钥检索该实体.
我最大的问题之一是你从哪里获得钥匙?我看到的一些文档显示了简单创建密钥的示例.我不明白这一点.似乎存储实体时,该put()
方法返回一个可以在以后使用的密钥.那么,如果数据存储区生成原始密钥,您如何才能创建密钥并定义ID?
我似乎正在努力的另一件事是带有钥匙的祖先的概念.您可以定义任何类型的父键.是否有预定义的架构?例如,如果我有一个名为"Person"的模型子类,并且我创建了一个类型为"Person"的键,我可以将该键用作任何其他类型的父键吗?就像我想要一个'鞋'键成为'人'键的孩子一样,我是否也可以声明'Car'键是同一个'Person'键的孩子?或者我会在添加"鞋子"键后无法使用?
我真的只是想对来自主要SQL背景的人的NDB数据存储及其API进行简单的解释.
我在使用谷歌的App引擎索引时遇到了麻烦.通过GoogleAppEngineLauncher运行我的应用程序时,该应用程序运行正常.部署应用程序时,我收到以下错误:
NeedIndexError: no matching index found.
The suggested index for this query is:
- kind: Bar
ancestor: yes
properties:
- name: rating
direction: desc
Run Code Online (Sandbox Code Playgroud)
在这行代码之后生成错误:
bars = bar_query.fetch(10)
Run Code Online (Sandbox Code Playgroud)
在上面的代码行之前,它显示为:
bar_query = Bar.query(ancestor=guestbook_key(guestbook_name)).order(-Bar.rating)
Run Code Online (Sandbox Code Playgroud)
我的index.yaml文件包含#AUTOGENERATED下面的确切"建议"索引:
- kind: Bar
ancestor: yes
properties:
- name: rating
direction: desc
Run Code Online (Sandbox Code Playgroud)
我可能错过了什么吗?我删除了index.yaml文件并再次部署了应用程序(通过命令行),并且上传了一个较少的文件 - 所以index.yaml文件就在那里.
一切都在当地很好.我正在研究最新的Mac OSx.用于部署的命令是:
appcfg.py -A app-name --oauth2 update app
Run Code Online (Sandbox Code Playgroud)
我实现的数据存储区基于留言簿教程应用程序.
任何帮助将不胜感激.
编辑:
我的ndb.Model定义如下:
class Bar(ndb.Model):
content = ndb.StringProperty(indexed=False)
lat = ndb.FloatProperty(indexed=False)
lon = ndb.FloatProperty(indexed=False)
rating = ndb.IntegerProperty(indexed=True)
url = ndb.TextProperty(indexed=False)
Run Code Online (Sandbox Code Playgroud) google-app-engine python-2.7 app-engine-ndb google-cloud-datastore
对不起,如果这个问题太简单了; 我只进入了9年级.
我正在尝试了解NoSQL数据库设计.我想设计一个最小化读/写次数的Google Datastore模型.
这是博客文章的玩具示例和一对多关系中的评论.哪个更有效 - 将所有注释存储在StructuredProperty中或使用Comment模型中的KeyProperty?
同样,目标是最小化对数据存储的读/写次数.您可以做出以下假设:
使用StructuredProperty:
from google.appengine.ext import ndb
class Comment(ndb.Model):
various properties...
class BlogPost(ndb.Model):
comments = ndb.StructuredProperty(Comment, repeated=True)
various other properties...
Run Code Online (Sandbox Code Playgroud)
使用KeyProperty:
from google.appengine.ext import ndb
class BlogPost(ndb.Model):
various properties...
class Comment(ndb.Model):
blogPost = ndb.KeyProperty(kind=BlogPost)
various other properties...
Run Code Online (Sandbox Code Playgroud)
请尽量提出与有效表示一对多关系相关的任何其他注意事项,以尽量减少对数据存储区的读/写次数.
谢谢.
google-app-engine one-to-many nosql app-engine-ndb google-cloud-datastore
这看起来很简单,但我没有找到如何从Google App Engine的ndb获取实体的ID.
class Message(ndb.Model):
name: ndb.StringProperty()
...
Run Code Online (Sandbox Code Playgroud)
创建一个消息对象:
message = Message(id=someId)
message.name = someName
message.put()
Run Code Online (Sandbox Code Playgroud)
后来当我检索实体时:
message = Message.query(Message.name==someName).fetch(1)
Run Code Online (Sandbox Code Playgroud)
现在如何获取消息的ID?谢谢.
ReferenceProperty在处理两个模块之间的引用时非常有用.Fox例子:
class UserProf(db.Model):
name = db.StringProperty(required=True)
class Team(db.Model):
manager_name = db.ReferenceProperty(UserProf, collection_name='teams')
name = db.StringProperty(required=True)
Run Code Online (Sandbox Code Playgroud)
它看起来不容易理解吗?
在使用NDB做同样的事情时,我们必须修改
db.ReferenceProperty(UserProf, collection_name='teams')
- > ndb.KeyProperty(kind=UserProf)
team_ins.manager_name.get()
会给你经理的名字为了让特定用户的所有团队成为管理者,我们必须这样做
for team in Team.query(Team.manager_name == user_ins.key):
print "team name:", team.name
Run Code Online (Sandbox Code Playgroud)正如您所看到的,处理这些场景在db中看起来比ndb更容易和可读.
提前致谢..
python google-app-engine app-engine-ndb google-cloud-datastore
摘自Python NDB概述:
当应用程序读取实体时,该实体会自动缓存; 这为经常读取的实体提供了快速(且便宜)的读取.
...
写入数据的NDB函数(例如put())在高速缓存失效后返回; Apply阶段异步发生.
在Youtube上观看,Google I/O 2011:更多9s请:在高复制数据存储的封面下,在13:11-ish,平均延迟是:
主从:
- 阅读:15ms
- 写:20ms
高复制:
- 阅读:15ms
- 写:45ms
从应用程序的角度来看,NDB对这些速度的影响有多大?
编辑:特别好奇时序统计(以毫秒为单位).
额外信用:我也听过尼克约翰逊提到每个约160毫秒的询问(2009年)[link]
NDB是否提供查询的任何速度优势?