【问题标题】:Self join with django ORM使用 django ORM 自加入
【发布时间】:2009-10-16 14:21:50
【问题描述】:

我有一个模型:

class Trades(models.Model):  
    userid     = models.PositiveIntegerField(null=True, db_index=True)
    positionid = models.PositiveIntegerField(db_index=True)
    tradeid    = models.PositiveIntegerField(db_index=True)
    orderid    = models.PositiveIntegerField(db_index=True)  
    ...

我想执行下一个查询:

select *
from trades t1
inner join trades t2
ON t2.tradeid = t1.positionid and t1.tradeid = t2.positionid

可以在不使用 Django ORM 的情况下完成吗? 谢谢!

【问题讨论】:

    标签: django


    【解决方案1】:

    选择 * ... 将需要更多的工作。如果您可以从右侧修剪所需的列

    table=SomeModel._meta.db_table
    join_column_1=SomeModel._meta.get_field('field1').column
    join_column_2=SomeModel._meta.get_field('field2').column
    join_queryset=SomeModel.objects.filter()
    # Force evaluation of query
    querystr=join_queryset.query.__str__()
    # Add promote=True and nullable=True for left outer join
    rh_alias=join_queryset.query.join((table,table,join_column_1,join_column_2))
    # Add the second conditional and columns
    join_queryset=join_queryset.extra(select=dict(rhs_col1='%s.%s' % (rhs,join_column_2)),
        where=['%s.%s = %s.%s' % (table,join_column_2,rh_alias,join_column_1)])
    

    添加其他列以供选择字典使用。

    额外的约束放在 ON() 之后的 WHERE 中,您的 SQL 引擎可能优化不佳。

    【讨论】:

      【解决方案2】:

      相信 Django 的 ORM 不支持对未指定为 ForeignKey 的任何内容进行联接(至少,上次我研究它时,这是一个限制。他们是虽然总是添加功能,所以它可能会偷偷溜进来)。

      因此,您的选择是重新构造表以便使用正确的外键,或者只执行原始 SQL 查询。

      我不会将原始 SQL 查询视为“黑客”。 Django 在how to do raw SQL Queries 上有很好的文档。

      【讨论】:

      • 在最近的 Django 版本中,您可以添加自联接。以 Django 版本 1.11.7 为例。 parent = models.ForeignKey('self',on_delete=models.CASCADE,db_column='parent_id',null=True, blank=True)
      猜你喜欢
      • 2014-08-30
      • 2019-11-15
      • 2014-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-11
      • 2019-08-12
      • 2015-08-15
      相关资源
      最近更新 更多