【问题标题】:Django ORM - building hierarchical data structure with multiple modelsDjango ORM - 使用多个模型构建分层数据结构
【发布时间】:2017-08-21 13:10:54
【问题描述】:

作为我正在从事的项目的一部分,我正在尝试为不同类型的对象构建分层数据结构。

我使用了django-mptt,它承诺通过快速查询以智能方式处理树。

问题是,我有多个模型需要参与到这个数据树中,所以我使用泛型关系来存储所需的数据。

我构建的模型的一个 sn-p:

class CPNode(MPTTModel):
    content_type = models.ForeignKey(ContentType, null=True, blank=True)
    object_id = models.PositiveIntegerField(null=True)
    content_object = GenericForeignKey('content_type', 'object_id')
    parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)
...

这给了我想要的,除了查询问题。

我认为查询所有数据将花费多次查询(每次我想获取 content_object 本身)。

是否有人知道我如何维护这种结构,同时能够在可扩展的查询中获取所有数据?

【问题讨论】:

  • 您遇到的具体问题是什么?您已为此选择使用关系数据库,因此您无法避免在这些类型的查询中使用一些 JOIN。如果您需要在查询中直接获取content_object,请使用prefetch_related,以避免多次查询。是否可扩展取决于您的数据。 NoSQL DB 可能更适合这种树。
  • 问题是,这些数据的很大一部分已经在生产中。所以转向 NoSQL DB 是我最后的选择。我还没有开始,但是提前考虑,似乎查询具有多种类型节点的大树会很麻烦。我有多种类型的资产,每种类型都由一个模型维护,每种资产都可以有不同类型的资产。

标签: python django django-orm django-mptt django-generic-relations


【解决方案1】:

关系数据库(至少是 SQL 数据库)在异构树方面并不是那么好...... MPTT 确实会通过避免递归查询来极大地提高读取性能,但这并不能解决GenericForeignKey hack - 没有办法在 SQL 级别实现这样的功能,所以如果你使用它,是的,你需要每个节点再查询一次才能获得有效的内容。

避免这些额外查询的唯一方法是在同一模型中填充每个节点子类型的每个字段,向其中添加“node_type”字段并使用每个节点类型的代理模型。代码不会很漂亮(一直在这里,完成了)但是,这里几乎没有其他选项......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-02
    • 2015-01-26
    • 1970-01-01
    • 2012-05-05
    • 2018-07-03
    • 2022-10-25
    • 2022-10-23
    • 1970-01-01
    相关资源
    最近更新 更多