我们的团队对AppEngine来说相对较新,我们仍然在学习绳索。我们使用简单的ndb.Model模型(即没有什么花哨的)和webapp2处理程序。该应用程序是无UI的,因为它只是一个宁静的API。
所以我们有一个定义如此的模型:
from google.appengine.ext import ndb
class Pasta(ndb.Model):
type = ndb.StringProperty(indexed=True)
name = ndb.StringProperty()
contents = ndb.JsonProperty()
modified_date = ndb.DateTimeProperty(auto_now=True)
added_date = ndb.DateTimeProperty(auto_now_add=True)
用例是我们想要添加一条记录,如果一条记录不存在,如果它确实存在,则返回它。我们可以在处理程序中查询它,甚至在那里创建一个并使用pasta.put()
实例方法来创建一个新的。但是,我们认为数据绑定代码属于模型,而不是处理程序,但是,如果我们没有弄错,在模型上下文中我们需要使用get_or_insert()
,这需要我们明确声明一个Key,正确?
如何在模型中处理这种逻辑? TIA。
答案 0 :(得分:1)
我不知道你为什么认为关于代码是否进入模型或者处理程序决定用于执行查询的方法的决定。您可以在任何一个地方使用get_or_insert
,但这确实意味着您需要知道所需实体的密钥。并且,您可以在任何一个地方进行查询。
如果您确实希望在模型中保留所有数据交互,一种可能的模式是在执行查询的模型上定义类方法,并返回现有实例或新实例。类似的东西:
class Pasta(ndb.Model):
...
@classmethod
def get_or_create(cls, type=None, name=None):
query = cls.query(cls.type=type, cls.name=name)
existing = query.get()
if existing:
return existing
else:
new_item = cls(type=type, name=name)
new_item.put()
return new_item
(注意我实际上并没有使用过ndb,但这或多或少是对的。)你需要确保在事务中调用这个方法。
答案 1 :(得分:0)
你有一个非常奇怪的论据,为什么创建一个实例(或记录)属于模型。
是的,模型代表数据,但处理程序是负责创建模型实例的人。您没有提供有关处理程序执行操作的足够信息。
首先,您需要确定要用作密钥的内容。如果您只是使用ndb随机创建的密钥,我不知道您如何确定该记录是否存在。我假设你想要使用Pasta.type或Pasta.name作为关键。
在这种情况下,'type'或'name'可能会作为参数提供给你的处理程序,你的处理程序会在从参数构造密钥后调用get_or_insert。
我还可以解释你的问题,因为你只想要给出意大利面模型的单一记录。这将是相当不典型的数据存储使用,但在这种情况下,在模型中使用方法来检查单个实例是否存在可能是有意义的。在这种情况下,您可以对密钥进行硬编码。
答案 2 :(得分:0)
密钥访问比查询更快,更便宜。最好在实现查询之前始终确定不能使用ID。另外,请记住,所有模型属性的默认索引状态都是True,因此每当设置模型时,始终将indexed = True / False置于状态是一个非常好的主意。许多情况下人们忘记了默认值是True,然后想知道为什么他们的索引存储只在查询少量属性时变得非常大。您是否想要其他模型属性的索引?