Python 分层数据建模-GAE

Python 分层数据建模-GAE,python,google-app-engine,bigtable,Python,Google App Engine,Bigtable,我是谷歌应用程序引擎(GoogleAppEngine)和谷歌数据存储(GoogleDatastore,bigtable)的新手,我怀疑哪种方法是设计所需数据模型的最佳方法 我需要创建一个层次结构模型,类似于产品目录,每个域都有一些子域。目前,产品的结构变化小于读取要求。葡萄酒示例: 起源(托斯卡纳、普里奥拉特、阿尔萨斯) 酿酒厂(仅属于一个产地) 葡萄酒(仅属于一家酒厂) 所有的关系都是不相交和不完整的。此外,按照要求的顺序,我们可能需要存储每种葡萄酒的使用计数器(可能需要交易) 按照文档的

我是谷歌应用程序引擎(GoogleAppEngine)和谷歌数据存储(GoogleDatastore,bigtable)的新手,我怀疑哪种方法是设计所需数据模型的最佳方法

我需要创建一个层次结构模型,类似于产品目录,每个域都有一些子域。目前,产品的结构变化小于读取要求。葡萄酒示例:

  • 起源(托斯卡纳、普里奥拉特、阿尔萨斯)
  • 酿酒厂(仅属于一个产地)
  • 葡萄酒(仅属于一家酒厂)
所有的关系都是不相交和不完整的。此外,按照要求的顺序,我们可能需要存储每种葡萄酒的使用计数器(可能需要交易)

按照文档的顺序,似乎有不同的潜在解决方案:

  • 祖先管理。使用父关系和事务
  • 伪祖先管理。使用db.ListProperty(db.Key)模拟祖先
  • 引用属性。明确指定类之间的关系
但按照获得葡萄酒的预期要求的顺序。。。有时根据品种,有时根据产地,有时根据酒厂。。。我担心使用这些结构的查询的行为(比如关系模型中的多个联接。如果您要求一个族的产品…您需要联接产品树中的最后一个深层限定符,并从该族开始联接)

也许最好创建一些重复的信息(按照google团队建议的顺序:操作成本很高,但存储成本不高,所以不应该将重复内容视为主要问题)

对其他类似问题的一些答复表明:

  • 将所有父ID存储为字符串中的层次结构。。。像路径属性一样
  • 复制饮料实体与树中所有父实体之间的关系
有什么建议吗


嗨,威尔

正如您在第二个示例中所表示的,我们的案例是一种更严格的分层方法。而查询是为了检索产品列表,只检索一个是不常见的

我们需要从一个产地、一个酿酒厂或一个品种中检索所有葡萄酒(如果我们认为该品种是严格等级树的另一个节点,这只是一个示例)

一种方法可以包括路径属性,如您所述:

  • /产地/{id}/酒庄/{id}/品种/{id}
要允许我应用如下查询从各种葡萄酒中检索葡萄酒列表:

wines_query = Wine.all()
wines_query.filter('key_name >','/origin/toscana/winery/latoscana/variety/merlot/')
wines_query.filter('key_name <','/origin/toscana/winery/latoscana/variety/merlot/zzzzzzzz')
wines\u query=Wine.all()
wines_query.filter('key_name>','/origin/toscana/winery/latoscana/variety/merlot/'))
wines_query.filter('key_name','/origin/toscana/'))

wines_query.filter('key_name我不确定除了问题中提到的查询之外,您还需要执行什么类型的查询,但是将数据存储在显式的祖先层次结构中会使您询问的查询很容易失效

例如,要获得来自特定产地的所有葡萄酒:

origin_key = db.Key.from_path('Origin', 123)
wines_query = db.Query(Wine).ancestor(origin_key)
或从特定酒庄获得所有葡萄酒:

origin_key = db.Key.from_path('Origin', 123)
winery_key = db.Key.from_path('Winery', 456, parent=origin_key)
wines_query = db.Query(Wine).ancestor(winery_key)
并且,假设您将品种存储为葡萄酒模型上的一个属性,那么特定品种的所有葡萄酒都非常简单

wines_query = Wine.all().filter('variety =', 'merlot')
这种严格的分层方法的一个可能的缺点是它可以强加给您的URL方案

Origin -> Winery -> Wine
为了构建检索葡萄酒的密钥,您必须知道葡萄酒产地和酒庄的密钥名称或ID。除非您已经获得了葡萄酒密钥的字符串表示形式。这基本上迫使您拥有以下形式之一的葡萄酒URL:

  • /origin/{id}/winery/{id}/wine/{id}
  • /wine/{不透明且不友好的数据存储键为字符串}
(第一个URL当然可以替换为查询字符串参数;重要的是,您需要三条不同的信息来识别给定的葡萄酒。)


也许我还没有想到这些URL方案的其他替代方案。

我不明白你的最新问题。
品种如何适应层次结构?来自不同产地和/或酿酒厂的葡萄酒不是有相同的品种吗?如果是这样,我想品种只能是一种属性在
Wine
模型上。我也不明白你的查询完成了什么,而我自己的示例查询没有完成。
Origin -> Winery -> Wine