标签: app-engine-ndb

我怎么知道ndb.Model.get_or_insert是创建了一个新实体还是现有实体?

对于以下(损坏)函数,我想True在创建或更新实体时返回,False否则.问题是我不知道是否get_or_insert()有现有实体或插入了实体.有没有一种简单的方法来确定这个?

class MyModel(ndb.Model):
    def create_or_update(key, data):
        """Returns True if entity was created or updated, False otherwise."""

        current = MyModel.get_or_insert(key, data=data)

        if(current.data != data)
            current.data = data
            return True

        return False
Run Code Online (Sandbox Code Playgroud)

python google-app-engine app-engine-ndb

10
推荐指数
1
解决办法
3599
查看次数

有效实现与Python NDB的一对多关系

我想听听您对有效实现与Python NDB的一对多关系的看法.(例如人(一)到任务(很多))

根据我的理解,有三种方法可以实现它.

  1. 使用'parent'参数
  2. 使用'重复'结构化属性
  3. 使用'重复'键属性

我通常会选择一种基于下面逻辑的方法,但这对你有意义吗?如果你有更好的逻辑,请教我.

  1. 使用'parent'参数

    • 这些实体之间需要进行交易操作
    • 这些实体之间需要双向引用
    • 强烈打算"亲子关系"
  2. 使用'重复'结构化属性

    • 不需要单独使用'many'实体(始终与'one'实体一起使用)
    • 'many'实体仅由'one'实体引用
    • '重复'的数量小于100
  3. 使用'重复'键属性

    • 需要单独使用'many'实体
    • "许多"实体可以由其他实体引用
    • '重复'的数量超过100

No.2增加了实体的大小,但我们可以保存数据存储区操作.(我们需要使用投影查询来减少反序列化的CPU时间).因此,我尽可能地使用这种方式.

我非常感谢你的意见.

python google-app-engine app-engine-ndb

10
推荐指数
2
解决办法
1378
查看次数

寻找提供与GAE数据存储查询匹配的项目的页面/项目计数/导航的想法/替代方案

我喜欢数据存储区的简单性,可扩展性和易用性; 并且在新的ndb库中找到的增强功能非常棒.

据我了解数据存储区最佳实践,当匹配查询的项目数量很大时,不应编写代码来提供匹配查询结果的项目和/或页面计数; 因为唯一的方法是检索所有资源密集的结果.

然而,在包括我们的许多应用程序中,通常希望看到匹配项目的计数并向用户提供导航到那些结果的特定页面的能力.数据存储分页问题由于需要解决fetch(limit,offset = X)的限制而变得更加复杂,如文章Paging Through Large Datasets中所述.为了支持推荐的方法,数据必须包含一个唯一值列,可以按结果显示的方式进行排序.此列将为每个结果页面定义一个起始值; 保存它,我们可以有效地获取相应的页面,允许按要求导航到特定页面或下一页面.因此,如果要显示以多种方式排序的结果,可能需要维护多个此类列.

应该注意的是,从SDK v1.3.1开始,Query Cursors是推荐的数据存储分页方式.它们有一些限制,包括缺乏对IN和!=过滤器运算符的支持.目前我们的一些重要查询使用IN,但我们将尝试使用OR编写它们以用于查询游标.

遵循建议的指南,可以为用户提供(下一个)(上一个)导航按钮,以及导航过程中的特定页面按钮.例如,如果用户按下(下一步) 3次,应用程序可以显示以下按钮,记住每个按钮的唯一起始记录或光标以保持导航效率:( 上一页)(第1页)(第2页)(页面) -3)(第4页)(下一步).

有些人建议分别跟踪计数,但是当允许用户查询将改变返回结果的丰富字段时,这种方法是不实际的.

我正在寻找有关这些问题的见解以及以下问题:

  1. 您在数据存储区应用中提供了哪些查询结果的导航选项来解决这些限制?

  2. 如果为用户提供有效的结果计数和整个查询结果集的页面导航是一个优先事项,那么应该放弃使用数据存储区,以支持现在提供的GAE MySql解决方案.

  3. 大表架构或数据存储区实现中是否有任何即将发生的更改,这些更改将提供有效计算查询结果的附加功能?

非常感谢您的帮助.

google-app-engine app-engine-ndb google-cloud-datastore

9
推荐指数
1
解决办法
1266
查看次数

使用ndb.KeyProperty如何引用相同的模型?

我有一个简单的场景,其中有一个User类,它有name,email和followers属性.

class User(ndb.Model):
    name = ndb.StringProperty(required = True)
    search_name = ndb.StringProperty(required = True)
    pw_hash = ndb.StringProperty(required = True)
    email = ndb.StringProperty()

    follows = ndb.KeyProperty(Follow, repeated=True)
    followers = ndb.KeyProperty(User, repeated=True)
Run Code Online (Sandbox Code Playgroud)

执行此操作时,我收到错误.

File "C:\ujjal\my project\cravel\code2\Users.py", line 46, in User
  followers = ndb.KeyProperty(User, repeated=True)
NameError: name 'User' is not defined
INFO     2012-09-11 11:45:23,953 dev_appserver.py:2967] "GET / HTTP/1.1" 500 -
Run Code Online (Sandbox Code Playgroud)

关于如何模仿"追随者"属性的任何建议都将受到高度赞赏.提前致谢

google-app-engine app-engine-ndb google-cloud-datastore

9
推荐指数
1
解决办法
1万
查看次数

为什么需要和默认在ndb中是独占的?

在旧的google appengine数据存储API中,"required"和"default"可以一起用于属性定义.使用ndb我得到了一个

ValueError: repeated, required and default are mutally exclusive.
Run Code Online (Sandbox Code Playgroud)

示例代码:

from google.appengine.ext import ndb
from google.appengine.ext import db

class NdbCounter(ndb.Model):
    # raises ValueError
    count = ndb.IntegerProperty(required=True, default=1)

class DbCounter(db.Model):
    # Doesn't raise ValueError
    count = db.IntegerProperty(required=True, default=1)
Run Code Online (Sandbox Code Playgroud)

我想实例化一个Counter而不必指定一个值.我还想避免有人将该值覆盖为None.构造上面的例子.我可能没有必需的属性,而是添加increment()方法.我仍然没有看到为什么必需和默认是互斥的原因.

这是一个错误还是一个功能?

python google-app-engine app-engine-ndb google-cloud-datastore

9
推荐指数
1
解决办法
1493
查看次数

在ndb中使用get_by_id获取多个实体

使用旧的数据库,我可以调用Model.get_by_id([1, 2, 3])获取实体列表.

Ndb Model.get_by_id不支持id列表作为参数.复制旧功能的最佳方法是什么?

python google-app-engine app-engine-ndb

9
推荐指数
1
解决办法
2926
查看次数

为App Engine NDB模型指定key_name的最佳方法是什么?

我正在尝试创建一个ndb模型,其中每个记录都有一个唯一的字段"name".我想将此字段定义为key_name字段,并使用它来查找记录.我是否必须包含名称字段,或者我可以以某种方式将key_name字段设置为用户可以指定的任意字符串,只要它是唯一的?

我正在考虑使用Model.get_or_insert来确保旧记录不会被覆盖,但有没有办法判断返回值是新创建还是预先存在?我希望能够在用户输入重复名称时显示错误消息.

最后,我尝试在DjangoForms模型上创建一个key_name字段,该模型使用上面的ndb模型作为元类,因此我可以使用djangoforms进行验证/呈现,但由于某种原因,我的定义字段不会显示.

class UserProfileForm(djangoforms.ModelForm):key_name = djangoforms.StringProperty()class Meta:model = UserProfile

google-app-engine app-engine-ndb

8
推荐指数
1
解决办法
3653
查看次数

使用带有多个ndb.get_multi_async的yield

我正在尝试从appengine数据存储区提高当前查询的效率.目前,我正在使用同步方法:

class Hospital(ndb.Model):
      name = ndb.StringProperty()
      buildings= ndb.KeyProperty(kind=Building,repeated=True)
class Building(ndb.Model):
      name = ndb.StringProperty()
      rooms= ndb.KeyProperty(kind=Room,repeated=True)
class Room(ndb.Model):
      name = ndb.StringProperty()
      beds = ndb.KeyProperty(kind=Bed,repeated=True)
class Bed(ndb.Model):
      name = ndb.StringProperty()
      .....
Run Code Online (Sandbox Code Playgroud)

目前我经历了愚蠢的事情:

currhosp = ndb.Key(urlsafe=valid_hosp_key).get()
nbuilds = ndb.get_multi(currhosp.buildings)
for b in nbuilds:
   rms = ndb.get_multi(b.rooms)
   for r in rms:
      bds = ndb.get_multi(r.beds)
      for b in bds:
          do something with b object
Run Code Online (Sandbox Code Playgroud)

我想使用get_multi_async将其转换为更快的查询

我的困难在于如何做到这一点?有任何想法吗?

最好的乔恩

python google-app-engine asynchronous app-engine-ndb

8
推荐指数
1
解决办法
1974
查看次数

如何在查询GAE数据存储区时修复索引错误?

当我尝试在按日期排序的数据存储上运行查询时,我收到以下错误:

NeedIndexError: no matching index found.
The suggested index for this query is:

- kind: Message
  properties:
  - name: author
  - name: ref
  - name: date
Run Code Online (Sandbox Code Playgroud)

如果我不尝试按日期排序,则查询运行时没有错误.数据存储索引下的appengine控制台说:

author ? , ref ? , date ?   
Serving
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?如何运行按日期排序的查询?谢谢!

这是我的实体定义:

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)
Run Code Online (Sandbox Code Playgroud)

这是失败的查询:

def readMessages( ref, user = None ):
    query = Message.query()
    query = query.filter(Message.ref == ref )
    if user: …
Run Code Online (Sandbox Code Playgroud)

google-app-engine app-engine-ndb google-cloud-datastore

8
推荐指数
1
解决办法
4063
查看次数

如何读取_pre_put_hook中的旧属性值

我正在尝试实现ndb模型审计,以便对属性的所有更改都存储在每个模型实例中.这是我选择实现的_pre_put_hook的代码.

def _pre_put_hook(self):
    # save a history record for updates
    if not (self.key is None or self.key.id() is None):
        old_object = self.key.get(use_cache=True)
        for attr in dir(self):
            if not callable(getattr(self, attr)) and not attr.startswith("_"):
                if getattr(self, attr) != getattr(old_object, attr):
                    logging.debug('UPDATE: {0}'.format(attr))
                    logging.debug('OLD: {0} NEW: {1}'.format(getattr(old_object, attr), getattr(self, attr)))
Run Code Online (Sandbox Code Playgroud)

问题是old_object总是填充有更新的self(对象)的相同值.如何在实际生成put()之前访问旧对象的属性值(_pre_put)?

google-app-engine app-engine-ndb google-cloud-datastore

8
推荐指数
1
解决办法
881
查看次数