python - Django ORM 和闭包表

标签 python sql django django-queryset transitive-closure-table

我正在尝试使用闭包表对组织为分层树的数据建模。代表树中节点的条目并不特别,定义如下。

class Region(models.Model):
    RegionGuid = models.CharField(max_length=40, unique=True, db_column='RegionGUID', blank=True)
    CustomerId = models.IntegerField(null=True, db_column='CustomerID', blank=True)
    RegionName = models.CharField(max_length=256, db_column='RegionName', blank=True)
    Description = models.TextField(db_column="Description", blank=True)
    class Meta:
        db_table = u'Region'

节点之间的路径使用以下闭包表定义。它由到祖先节点的FK、到后代节点的FK以及Ancestor和Descendant之间的路径长度(即节点数)组成:

class RegionPath(models.Model):
    Ancestor = models.ForeignKey(Region, null=True, db_column='Ancestor', blank=True)
    Descendant = models.ForeignKey(Region, null=True, db_column='Descendant', blank=True)
    PathLength = models.IntegerField(null=True, db_column='PathLength', blank=True)
    class Meta:
        db_table = u'RegionPath'

现在如何检索所有 Region 行及其各自的父节点(即 RegionPath.PathLength = 1 的位置)?我的 SQL 有点生疏,但我认为 SQL 查询应该看起来像这样。

SELECT r.* from Region as r 
LEFT JOIN 
(SELECT r2.RegionName, p.Ancestor, p.Descendant from Region as r2 INNER JOIN RegionPath as p on r2.id = p.Ancestor WHERE p.PathLength = 1) AS Parent
on r.id = Parent.Descendant

非常感谢使用 Django 的 QuerySet API 表达这一点的任何帮助。

最佳答案

像这样将 related_name 添加到外键:

class RegionPath(models.Model):
    Ancestor = models.ForeignKey(Region, null=True, db_column='Ancestor', blank=True, related_name="ancestor")
    Descendant = models.ForeignKey(Region, null=True, db_column='Descendant', blank=True, related_name="descendants")
    PathLength = models.IntegerField(null=True, db_column='PathLength', blank=True)
    class Meta:
        db_table = u'RegionPath'

您可以查询任一关系:

children = Region.objects.filter(ancestors__PathLength=1)
parents = Region.objects.filter(descendants__PathLength=1)

我在一个非常相似的模型上进行了测试。您可能必须添加 .distinct(),您可能希望添加 select_related() 以减少查询。

关于python - Django ORM 和闭包表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14789046/

相关文章:

sql - Access IIF 到 SQL 语句转换

python - DRF - 如何从查询集中获取单个项目?

python - 将 pandas 系列替换为另一个系列中最接近的值

python - 我陷入了 SKlearn 的属性错误

mysql - Oracle MySQL : Cannot add foreign key constraint

django - 你是如何设置你的 Django 开发环境的?

ios - 使用 Twitter 在 iPhone 中登录用户并将经过身份验证的用户保存到远程 Django 应用程序

python - 如何将字典列表转换为单个 Pandas 数据框?

python - 转换 Python Lambda 函数而不将值返回给 Pyspark

mysql - 在mysql中,如何根据不同的表动态创建 View ?