首页 > 解决方案 > Django TruncDate 给出 null

问题描述

我正在使用Django 2.2

我正在使用 Django 查询过滤记录,例如

from datetime import datetime
from django.db.models.functions import TruncDate

start_date = datetime.strptime('2020-02-01', '%Y-%m-%d').date()
end_date = datetime.strptime('2020-03-31', '%Y-%m-%d').date()

lead_list = LeadList.objects.all()

# Filter query
query = LeadListEntry.objects.filter(
    lead_list__in=lead_list
  )

# Filter by start date
query = query.filter(
    created__gte=start_date
  )

# Filter by end date
query = query.filter(
    created__lte=end_date
  )

# Annotate date
query = query.annotate(
     created_date=TruncDate('created')
   ).order_by(
     'created_date'
   ).values('created_date').annotate(
     **{'total': Count('created')}
   )

生成的 SQL 查询是

SELECT 
    DATE(CONVERT_TZ(`lead_generation_leadlistentry`.`created`, 'UTC', 'UTC')) AS `created_date`, 
    COUNT(`lead_generation_leadlistentry`.`created`) AS `total`
FROM `lead_generation_leadlistentry` 
WHERE (
    `lead_generation_leadlistentry`.`lead_list_id` IN (
        SELECT 
            U0.`id` FROM `lead_generation_leadlist` U0 
        WHERE 
            U0.`deleted` IS NULL
    )
    AND `lead_generation_leadlistentry`.`created` >= '2020-02-01 00:00:00' 
    AND `lead_generation_leadlistentry`.`created` <= '2020-03-31 00:00:00'
)
GROUP BY DATE(CONVERT_TZ(`lead_generation_leadlistentry`.`created`, 'UTC', 'UTC'))
ORDER BY `created_date` ASC

这在本地和登台服务器上表现不同

本地开发服务器

+--------------+-------+
| created_date | total |
| ------------ | ----- |
| 2020-02-25   | 15    |
| 2020-02-27   | 10    |
+--------------+-------+

登台服务器

+--------------+-------+
| created_date | total |
| ------------ | ----- |
| null         | 15    |
+--------------+-------+

日期列是null

注意:Django 启用了时区USE_TZ=True

LeadListEntry模型

class LeadListEntry(models.Model):
    lead_list = models.ForeignKey(LeadList, on_delete=models.CASCADE, related_name='lead_list_entry')
    data = models.TextField(help_text='Lead List entry data. (JSON data)', blank=False)

    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

标签: pythonmysqldjangotimezone

解决方案


这是用户遇到相同错误的解决方案

该错误与Django无关,而是与MySQL数据库设置有关。

日期字段返回null,因为CONVERT_TZ不起作用。这可能是由于 MySQL 数据库中没有时区数据。

要导入时区数据,请执行以下命令

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql

导入后重启mysql服务器。


推荐阅读