【问题标题】:Rewrite PostgreSQL to Django ORM将 PostgreSQL 重写为 Django ORM
【发布时间】:2017-05-03 10:25:59
【问题描述】:

如果可以在没有原始 SQL 的情况下将此 PostgreSQL 查询重写为 Django ORM,我自己尝试过,但没有成功。

这是基金的模型

class Fund(models.Model):
    name = models.CharField(max_length=320, unique=True)
    fund_manager = models.CharField()
     .............. 

这是NAV的模型

class NAV(models.Model):
    price = models.DecimalField(max_digits=9, verbose_name=_('NAV'))
    date = models.DateField(verbose_name=_('date'))
    fund = models.ForeignKey('Fund', related_name='navs')
    created_date = models.DateTimeField(default=now)

这是有效的 sql 查询,需要重写为 Django ORM

select * from finance_fund ORDER BY(
  (select price from finance_nav where date='2016-11-08' and fund_id=finance_fund.id) / 
  (select price from finance_nav where date='2016-11-07' and fund_id=finance_fund.id)
)

所以基本上我需要通过外键反向关系的两个简单查询的除法结果排序

提前致谢!

【问题讨论】:

    标签: django postgresql django-orm


    【解决方案1】:

    仅适用于原始 SQL。尝试类似:

    qs = Fund.objects.annotate(x=RawSQL("""
        (select price from finance_nav where finance_fund.id=fund_id and date=%s limit 1) 
        / (select price from finance_nav where finance_fund.id=fund_id and date=%s limit 1)
        """,('2016-11-08', '2016-11-07'))).order_by('x')
    

    【讨论】:

    • 那么,我以后可以过滤它吗?例如qs.filter()
    • 是的。你甚至可以参考.x
    • 哇,所以它返回正常的查询集而不是原始查询集(objects.raw),在我看来问题已经解决了。
    • 我对每个基金的导航都有唯一的日期,所以恕我直言 limit 1 在这里是多余的。
    • 所以你也可以添加一个 unique_together = (('fund', 'date'),) 到 NAV :-)
    猜你喜欢
    • 1970-01-01
    • 2021-10-16
    • 2011-03-11
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 2016-09-23
    相关资源
    最近更新 更多