TruncDay在Django + MySQL5.5中不起作用

时间:2016-11-15 19:04:30

标签: python mysql django

让我们用这个模型创建一个小的Django应用程序:

class Thing(models.Model):
    timestamp = models.DateTimeField(auto_now_add=True)

现在让我们尝试获取此日期的截断版本:

Thing.objects.create()

print Thing.objects.annotate(
    truncstamp=TruncDay('timestamp')
).values('truncstamp')

如果我们只是在Django中运行查询集,我们会得到一个可能解释的错误:

ValueError: Database returned an invalid datetime value. Are time zone definitions for your database and pytz installed?

但是我安装了pytz,并且我已经在我的数据库中加载了时区。我的意思是,这个查询有效:

SELECT CONVERT_TZ(NOW(), 'SYSTEM', 'UTC');

让我们看看它试图运行的查询:

print Thing.objects.annotate(
    truncstamp=TruncDay('timestamp')
).values('truncstamp').query

这会产生查询:

SELECT CAST(DATE_FORMAT(CONVERT_TZ(`stuff_thing`.`timestamp`, 'UTC', UTC), '%Y-%m-%d 00:00:00') AS DATETIME) AS `truncstamp` FROM `stuff_thing`

如果我尝试在MySQL中运行此查询,则无效。

ERROR 1054 (42S22): Unknown column 'UTC' in 'field list'

以下是仍然提供相同错误的查询的最小子集:

SELECT CONVERT_TZ(timestamp, 'UTC', UTC) from stuff_thing;

我们在这做什么?从UTC转换为UTC?为什么没有引用第二个UTC? Django发出无效的SQL吗?即使你引用了第二个'UTC',你从转换得到的只是NULL。为什么它甚至试图从UTC转换为UTC?我们不能跳过这一步吗?

这是一个新生成的应用程序,默认设置。我注意到如果我注释掉这个默认设置,查询将运行:

# TIME_ZONE = 'UTC'

现在结果以美国/芝加哥时区回归。

1 个答案:

答案 0 :(得分:0)

喔。精彩。我猜MySQL会缓存查询,缓存区分大小写。看到这种疯狂:

mysql> SELECT CAST(DATE_FORMAT(CONVERT_TZ(`stuff_thing`.`timestamp`, 'UTC', 'UTC'), '%Y-%m-%d 00:00:00') AS DATETIME) AS `truncstamp` FROM `stuff_thing` LIMIT 21;
+------------+
| truncstamp |
+------------+
| NULL       |
| NULL       |
+------------+
2 rows in set (0.00 sec)

mysql> SELECT CAST(DATE_FORMAT(CONVERT_TZ(`stuff_thing`.`timestamp`, 'UTC', 'UTC'), '%Y-%m-%d 00:00:00') AS DATETIME) as `truncstamp` FROM `stuff_thing` LIMIT 21;
+---------------------+
| truncstamp          |
+---------------------+
| 2016-11-15 00:00:00 |
| 2016-11-15 00:00:00 |
+---------------------+
2 rows in set (0.00 sec)

我重新启动了mysql,现在两个查询都有效。我想它已被破坏,因为我导入时区而没有重新启动它。