我正在尝试使用Django从sqlite数据库查询数据。
模型
class SolarEntryHour(models.Model):
time = models.DateTimeField()
device = models.ForeignKey(Device)
lW = models.DecimalField(max_digits=9, decimal_places=3)
class Meta:
unique_together = (("time", "device"))
我如何尝试访问数据
start = datetime.datetime.utcnow()+relativedelta(hour=0, minute=0, second=0, microsecond=0)
end = datetime.datetime.utcnow()
ticks = SolarEntryHour.objects.filter(
time__range=(start, end),
device = str(deviceID)
)
发生了什么
Exception Value:
list index out of range
Exception Location: /usr/lib/python2.7/dist-packages/django/db/backends/util.py in typecast_timestamp, line 97
当查询实际执行时(在迭代“ticks”时)似乎发生异常
查询Django尝试执行,print start; print end
的输出看起来很好
2013-01-01 00:00:00 - 2013-01-01 20:47:24.245942
SELECT "charts_solarentryhour"."id", "charts_solarentryhour"."time", "charts_solarentryhour"."device_id", "charts_solarentryhour"."lW"
FROM "charts_solarentryhour"
WHERE ("charts_solarentryhour"."device_id" = 1 AND "charts_solarentryhour"."time"
BETWEEN 2013-01-01 00:00:00 and 2013-01-01 20:47:24.245942)
修改
我想我找到了问题,但我不知道这是预期的行为还是Django Bug。
表“charts_solarentryhour”的“time”字段定义为:
time = models.DateTimeField()
此表由数据库触发器填充,而不是输入此字段的完整日期时间,soley strftime('%Y-%m-%d %H', 'now')
当Django然后执行查询时,它在解析查询结果时失败,因为从数据库返回的字符串中没有分钟和秒数(这就是为什么列表索引超出范围异常的原因)
不填充整个日期时间字段是不好的做法? Django不应该添加一些零吗? 有没有很好的方法来解决这个问题而不回退原始查询执行?
答案 0 :(得分:0)
问:不填充整个日期时间字段是不好的做法吗?
是的 - 有很多工具可以很好地解析格式良好的标准日期格式。因此,当您发明自己的格式时,期望发生不好的事情。 Django和几乎所有框架都希望您使用标准字段类型的既定约定。
问:Django不应该添加一些零吗?
不 - 这将是黑魔法。 “2013-01-10 10”没有传统意义。
问:有没有什么好办法可以解决这个问题而不回退原始查询执行?
是 - 请在此处查看答案:Format for DateTimeField
答案 1 :(得分:0)
这不是Django的问题 是dateutil的relativedelta函数的奇怪行为
你必须写下以下内容:
start = datetime.datetime.utcnow()+ relativedelta(小时= 0,分钟= 0,秒= 0,微秒= 0)
而不是
start = datetime.datetime.utcnow()+ relativedelta(小时= 0,分钟= 0,秒= 0,微秒= 0)
小时更改替换(并且不添加)初始值
>>>import datetime
>>>from dateutil.relativedelta import relativedelta
>>>t1 = datetime.datetime.utcnow()
>>>t1
datetime.datetime(2013, 11, 20, 18, 55, 11, 895897)
>>>t2 = t1 + relativedelta(hour=1, minute=3, second=7, microsecond=1)
>>>t2
datetime.datetime(2013, 11, 20, 1, 3, 7, 1)
>>>t3 = t1 + relativedelta(hours=1, minutes=1, seconds=1, microseconds=1)
>>>t3
datetime.datetime(2013, 11, 20, 19, 56, 12, 895898)