Django:加入DateTimeField

时间:2016-12-01 15:13:15

标签: python sql django django-orm

如何在DateTimeField上加入两个模型?

class ExchangeRate(models.Model):
    date = models.DateTimeField(...)
    usd_rub = models.DecimalField(...)

class LedgerEntry(models.Model):
    account = models.ForeignKey(...)
    date = models.DateTimeField(...)
    amount = models.DecimalField(...)

这是我想要的一个例子。请注意,ExchangeRate表中的记录具有任意日期和时间(与LedgerEntry表中的日期不对应)。可以在日期或时间加入ExchangeRates(可以安全地忽略分钟,秒等)。

        ExchangeRate                        LedgerEntry            
–––––––––––––––––––––––––––-    –––––––––––––––––––––––––––---------
|      Date     |  USD_RUB |    | account |      Date     | Amount |
|---------------|----------|    |–––––––––|---------------|--------|
| 29 Nov, 14:15 |  100.00  |    |    13   | 29 Nov, 14:40 |  10.0  |
| 29 Nov, 14:04 |  200.00  |    |    37   | 29 Nov, 14:45 |  11.0  |
| 29 Nov, 13:51 |  150.00  |    |    19   | 01 Oct, 10:32 |  12.0  |
| ............. | .........|    –––––––––––––––––––––––––––---------
| 01 Oct, 10:23 |  500.00  |
–––––––––––––––––––––––––––-

                           Join result                             
–––––––––––––––––––––––––––-------------------------------------
| account |      Date     | Amount |  USD_RUB | USD_RUB amount |
|–––––––––|---------------|--------|----------|----------------|
|    13   | 29 Nov, 14:40 |  10.0  |  100.00  |    1000.0      |
|    37   | 29 Nov, 14:45 |  11.0  |  100.00  |    1100.0      |
|    19   | 01 Oct, 10:32 |  12.0  |  500.00  |    6000.0      |
–––––––––––––––––––––––––––-------------------------------------

我知道我可以从数据库中查询所有这些对象并且"加入"他们在Python中。数据库中有数千条记录,因此效率非常低,因为在查找分类帐条目的相应汇率时会产生大量的单一选择语句。

1 个答案:

答案 0 :(得分:0)

起初我想使用原始SQL进行左连接,但我已经找到了使用extra()的解决方案:

referral_profits = LedgerEntry.objects.filter(
    balance=request.user.balance,
    reason=LedgerEntry.REASON_DEBIT
).extra(
    select={ 'usd_value': r'''
        SELECT usd_rub
        FROM stats_exchangerate
        WHERE 
            date_trunc('hour', billing_ledgerentry.date) = 
            date_trunc('hour', stats_exchangerate.date)
        LIMIT 1
        '''
    },
)
for x in referral_profits:
    print(x, x.usd_value, x.date)

请注意date_trunc是Postgres-speficic函数。

编辑:它有效,但效率非常低。看起来最后的手段是使用纯SQL吗?

相关问题