1

从传统关系数据库迁移到非关系数据库(如App Engine数据存储区)时,如何正确进行数据建模存在大量问题。Google App Engine数据存储建模问题

我已经多次阅读NDB官方文档,并在互联网上尝试了几个教程,但是,我仍然陷入困境。

我正在开发一个财务应用程序,它可以记录我所有的个人开支。这意味着我设计了一个名为Expense的实体,其中包含一些属性。作为费用的一部分,我还设计了一个供应商实体来存储与商家相关的信息。

下面是执行:

class Expense(ndb.Model): 
    amount = ndb.FloatProperty(required=False) 
    description = ndb.StringProperty() 
    vendor = ndb.KeyProperty(kind=Vendor) 

class Vendor(ndb.Model): 
    companyName = ndb.StringProperty(required=False) 
    friendlyName = ndb.StringProperty(required=False, default="") 

这是为了获取消费信息的代码:

def get(self): 
    template_page = "expense.html" 
    template_values = {'expense':Expense.query()} 

    self.renderTemplatePage(template_page, template_values) 

我的设计面临的问题上面是如何中检索费用和供应商信息并把它传递给JINJA来渲染它。正如我所料,Expense类中的Vendor属性只是一个Key而不是对象本身。所以JINJA无法理解表达式{{expense.vendor.friendlyName}}

虽然这个问题似乎是技术性的,但我相信我的智慧与非关系数据库的概念以及我应用于传统类型的设计有关解决方案。

另一种方法是使用StructuredProperty而不是KeyPrperty。但是,一个解决方案要求是能够重命名供应商友好名称,并且这会影响所有现有费用。追踪每个建筑物并找出变化是疯狂的。

在放弃App Engine并转移到Google Cloud SQL之前,我想听一些关于如何解决这个数据建模场景的建议。也许我不建议在非关系型数据库中使用我需要构建的解决方案。

Thansk对此有任何支持。

回答

2

在模板中,你可以这样做:

{{ expense.vendor.get().friendlyName }} 

或者你可以将属性添加到您的模型:

class Expense(ndb.Model): 
    amount = ndb.FloatProperty(required=False) 
    description = ndb.StringProperty() 
    vendor = ndb.KeyProperty(kind=Vendor) 

    @property 
    def vendor_name(self): 
     return self.vendor.get().friendlyName 

这将允许在你的模板:

{{ expense.vendor_name }} 

要停止这样做效率低下,您可以在显示费用清单前拨打供应商,拨打电话get内循环只是本地内存查找:

def get(self): 
    template_page = "expense.html" 
    expenses = Expense.query().fetch() 
    ndb.get_multi([e.vendor for e in expenses]) 
    template_values = {'expense':expenses} 

    self.renderTemplatePage(template_page, template_values) 
+0

感谢您的帮助,格雷格。非常感激! 这两种方法都很好。 现在,就设计而言,这究竟是怎么回事?我将向费用实体添加更多KeyProperty,例如类别和付款。 我仍然需要改变我对非关系数据库数据建模的想法。我不清楚何时选择其中一种或其他数据库技术。 –

+0

@FabioMoggi与ndb关系的讨论:http:// stackoverflow。com/q/14739044/584846 –

+0

感谢提示@BrentWashburne –

相关问题