2013-01-01 57 views
1

我想從使用Django的sqlite數據庫中查詢數據。使用Django ORM過濾日期時間範圍時出現奇怪的行爲

模型

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 

的例外似乎發生,當實際執行的查詢(上迭代「蜱」) 查詢的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 = models.DateTimeField()
這個表由一個數據庫觸發器,不輸入完整的日期時間到該字段填入,索利strftime('%Y-%m-%d %H', 'now')

當Django然後執行查詢,它在解析查詢結果時失敗,因爲從數據庫返回的字符串中沒有分秒數(這就是爲什麼列表索引超出範圍異常被拋出的原因)

是不是很差練習不填充整個日期時間字段?
不應該Django能夠添加一些零?
有沒有什麼好方法可以解決這個問題,而不會退回原始查詢執行?

+0

您可以顯示* how *你正在迭代滴答? – jknupp

+1

你是什麼意思,似乎會發生?你有回溯。什麼是97號線? –

+0

第97行的代碼還沒有被我寫過,並且是django特有的。 執行操作時出現錯誤: '對於滴答滴答:'' – Simbi

回答

0

問:不填充整個日期時間字段是不好的做法嗎?

是的 - 這裏有很多工具可以很好地解析格式良好的標準日期格式。所以當你發明你自己的格式時,預計會發生不好的事情。 Django和幾乎所有的框架都希望你能夠使用已有的標準字段類型的約定。

問:Django不應該能夠添加一些零嗎?

不,這將是黑暗的魔法。 「2013-01-10 10」沒有傳統意義。

問:有沒有什麼好的方法可以解決這個問題而不會退回到原始查詢執行?

是 - 在這裏看到了答案:Format for DateTimeField

0

這不是Django的 的一個問題是dateutil的relativedelta功能的一個奇怪的行爲

你必須寫:

start = datetime.datetime.utcnow()+ relativedelta(hours = 0,minutes = 0,seconds = 0,microseconds = 0)

和不

開始= 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)