GAE数据存储ndb模型以5种不同的方式访问

时间:2014-06-17 10:54:28

标签: python google-app-engine app-engine-ndb

我经营一个在线市场。我不知道访问NDB模型的最佳方式。我担心它真的很乱,我真的不知道转向哪个方向。如果您没有时间做出完整的回复,我很高兴看到有关NDB最佳做法的文章

我有这些类,它们以不同的方式相互关联:

  • User(webapp2_extras.appengine.auth.models.User)控制卖家登录
  • Partner(ndb.Model)包含有关卖家的信息
  • menuitem(ndb.Model)包含有关菜单上的项目的信息
  • order(ndb.Model)包含买家信息&有关订单的信息(所有购买都是"客人"购买)
  • Preapproval(ndb.Model)包含从PayPal保存的付款信息

他们如何联系。

User - Partner

一对一的关系。两者都有"电子邮件地址"领域。如果这些匹配,则可以从伙伴检索用户,反之亦然。例如:

 user = self.user
 partner = model.Partner.get_by_email(user.email_address)

我们在合作伙伴模型中的位置:

 @classmethod
 def get_by_email(cls, partner_email):
    query = cls.query(Partner.email == partner_email)
    return query.fetch(1)[0]

Partner - menuitem

menuitemPartner的孩子。像这样创建:

myItem = model.menuitem(parent=model.partner_key(partner_name))

menuitems的引用方式如下:

menuitems = model.menuitem.get_by_partner_name(partner.name)

get_by_partner_name就是这样:

 @classmethod
 def get_by_partner_name(cls, partner_name):
   query = cls.query(
      ancestor=partner_key(partner_name)).order(ndb.GenericProperty("itemid"))
   return query.fetch(300)

并且partner_key()是一个浮动在model.py文件顶部的函数:     def partner_key(partner_name = DEFAULT_PARTNER_NAME):       return ndb.Key(' Partner',partner_name)

Partner - order

每个Partner可以包含多个order个。 order的父级为Partner。如何创建订单:

    partner_name = self.request.get('partner_name')
    partner_k = model.partner_key(partner_name)
    myOrder = model.order(parent=partner_k)

如何引用订单:

myOrder_k = ndb.Key('Partner', partnername, 'order', ordernumber)
myOrder = myOrder_k.get()

有时是这样的:     order = model.order.get_by_name_id(partner.name,ordernumber)

(我们在model.order的地方:     @classmethod     def get_by_name_id(cls,partner_name,id):     return ndb.Key(' Partner',partner_name,' order',int(id))。get() )

这并不是特别有效,特别是因为我经常需要在数据存储区中查找合作伙伴才能提取订单。例如:

user = self.user
partner = model.Partner.get_by_email(user.email_address)
order = model.order.get_by_name_id(partner.name, ordernumber)

已经拼命想让myOrder = order.get_by_id(ordernumber)之类的东西变得简单起作用,但似乎让合作伙伴父母停止工作。

Preapproval - order

一对一的关系。每个订单都可以预先批准'。链接:预批准类中的字段:order = ndb.KeyProperty(kind=order)

创建预批准:

item = model.Preapproval( order=myOrder.key, ...)

访问预批准:

preapproval = model.Preapproval.query(model.Preapproval.order == order.key).get()

这对我来说似乎是最简单的方法。

TL; DR:我正在联系&以多种方式访问​​模型,并且它不是非常系统化的。

2 个答案:

答案 0 :(得分:0)

好的,我认为清理它的第一步如下:

在.py文件的顶部,导入所有模型,因此您不必继续使用model.ModelName。如果代码清理了一点。 model.ModelName变为ModelName

清理它的第一个最佳实践是始终使用大写字母作为命名类的第一个字母。型号名称是一个类。在上面,您有混合型号名称,如合作伙伴,订单,menuitem。这让人难以理解。另外,当您使用order作为模型名称时,最终可能会出现冲突。在上面,您将order重新定义为变量两次。使用Order作为模型名称,this_order作为查找,order_key作为关键,以消除一些冲突。

好的,让我们从那里开始

答案 1 :(得分:0)

用户 - Parner

您可以替换:

 @classmethod
 def get_by_email(cls, partner_email):
    query = cls.query(Partner.email == partner_email)
    return query.fetch(1)[0]

使用:

 @classmethod
 def get_by_email(cls, partner_email):
    query = cls.query(Partner.email == partner_email).get()

但由于交易问题,最好使用实体组:用户应该是合作伙伴的父母。

在这种情况下,您可以使用get_by_email而不是查询:

user = partner.key.parent().get()

或者执行祖先查询以获取合作伙伴对象:

partner = Partner.query(ancestor=user_key).get()

查询

如果您不需要,请不要使用fetch()。使用查询作为迭代器。 而不是:

return query.fetch(300)

只是:

return query

然后使用query as:

for something in query:
    blah

关系:合作伙伴 - 菜单项和合作伙伴 - 订单

为什么使用实体组?祖先不用于建模1到N关系(必然)。祖先用于交易,定义实体组。它们在组合关系中很有用(例如:伙伴 - 用户)

您可以使用KeyProperty进行关系。 (多值(即重复=真)或不,取决于关系的方向)

  

已经拼命想要像myOrder = order.get_by_id(ordernumber)这样简单的工作,但似乎让合作伙伴父母停止工作。

如果您在此关系中停止使用祖先,则没问题。


  

TL; DR:我正在联系&以多种方式访问​​模型,并不是非常系统化的

没有一种系统的方式来链接模型。它取决于许多因素:基数,每一方可能的项目数量,需要交易,组成关系,索引,未来查询的复杂性,优化的非规范化等。