Django:加入DateTimeField

2024-05-23 20:54:55 发布

您现在位置:Python中文网/ 问答频道 /正文

如何加入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“连接”它们。数据库中有数千条记录,因此这是非常低效的,因为在为分类账分录寻找相应的汇率时,它会生成大量的单选语句。你知道吗


Tags: datemodelexchangeratemodelsaccountamountoctnov
1条回答
网友
1楼 · 发布于 2024-05-23 20:54:55

一开始我想用原始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的一个特殊函数。你知道吗

编辑:行得通,但效率太低了。看来最后的办法是使用纯SQL?你知道吗

相关问题 更多 >