文章目錄
- Django--ORM查詢-時間比對
-
- 1. 引入
- 2. 查錯
- 3. 解決
- 4. 知識補充
Django–ORM查詢-時間比對
1. 引入
帥帥的我遇到了一個問題,我需要從
Student
表中,取出建立時間
c_time
在
2019-3-20
的記錄。
- 首先我們确認
類型c_time
In [5]: s1 = Student.objects.get(name='灰原') In [6]: type(s1.c_time) Out[6]: datetime.datetime
- 再檢視表内資料
In [10]: Student.objects.all() Out[10]: <QuerySet [ <Student: id<1>name[柯南]gender(男)age|16|c_time:2019-03-20 15:25:09+00:00>, <Student: id<2>name[元太]gender(男)age|16|c_time:2019-03-20 15:26:16+00:00>, <Student: id<3>name[薩斯給]gender(男)age|16|c_time:2019-03-20 15:27:56+00:00>, <Student: id<4>name[步美]gender(女)age|16|c_time:2019-03-20 15:28:16+00:00>, <Student: id<5>name[灰原]gender(女)age|16|c_time:2019-03-20 15:28:16+00:00>, <Student: id<8>name[納魯淘]gender(男)age|16|c_time:2019-03-20 15:28:16+00:00> ... ]>
- 建立日期在
資料不少2019-3-20
- 建立日期在
2. 查錯
- 查詢
In [11]: Student.objects.filter(c_time__date=datetime.date(2019, 3, 20))
Out[11]: <QuerySet []>
In [12]: s1.c_time.date()==datetime.date(2019, 3, 20)
Out[12]: True
- 查詢結果為空
- 有滿足條件記錄
- 對比
In [19]: Student.objects.filter(c_time=t1)
Out[19]: <QuerySet [
<Student: id<4>name[步美]gender(女)age|16|c_time:2019-03-20 15:28:16+00:00>,
<Student: id<5>name[灰原]gender(女)age|16|c_time:2019-03-20 15:28:16+00:00>,
...
]>
In [20]: td1 = t1.date()
In [21]: Student.objects.filter(c_time__date=td1)
Out[21]: <QuerySet []>
- 發現隻有調用
屬性出錯__date
- 驗證
In [22]: r1 = Student.objects.filter(c_time=t1)
In [23]: str(r1.query)
Out[23]:'''
SELECT `book_student`.`id`, `book_student`.`name`, `book_student`.`age`, `book_student`.`gender`, `book_student`.`c_time`, `book_student`.`college_id`
FROM `book_student`
WHERE `book_student`.`c_time` = 2019-03-20 15:28:16'
'''
In [24]: r2 = Student.objects.filter(c_time__date=td1)
In [26]: str(r2.query)
Out[26]: '''
SELECT `book_student`.`id`, `book_student`.`name`, `book_student`.`age`, `book_student`.`gender`, `book_student`.`c_time`, `book_student`.`college_id`
FROM `book_student`
WHERE DATE(CONVERT_TZ(`book_student`.`c_time`, 'UTC', 'Asia/Shanghai')) = 2019-03-20
'''
- CONVERT_TZ(dt,from_tz,to_tz):轉換datetime值dt,從 from_tz 由給定轉到 to_tz 時區給出的時區,并傳回的結果值。 如果參數無效該函數傳回NULL。
- 測試sql
mysql> SELECT CONVERT_TZ('20190320000000', 'UTC', 'Asia/Shanghai');
+------------------------------------------------------+
| CONVERT_TZ('20190320000000', 'UTC', 'Asia/Shanghai') |
+------------------------------------------------------+
| null |
+------------------------------------------------------+
1 row in set (0.00 sec)
- 找到了問題,我的MySQL資料庫應用的mysql(即系統自帶的那個資料庫)資料庫中沒有對應的time_zone表
- 解決方法請參閱:2lovecode的部落格
3. 解決
- 驗證sql
mysql> SELECT CONVERT_TZ('20190320000000', 'UTC', 'Asia/Shanghai');
+------------------------------------------------------+
| CONVERT_TZ('20190320000000', 'UTC', 'Asia/Shanghai') |
+------------------------------------------------------+
| 2019-03-20 08:00:00 |
+------------------------------------------------------+
1 row in set (0.00 sec)
配置好後,
sql
驗證通過
- 驗證orm
In [32]: Student.objects.filter(c_time__date=datetime.date(2019, 3, 20)).count()
Out[32]: 8
In [33]: Student.objects.filter(c_time__date='2019-03-20').count()
Out[33]: 8
通過驗證,大吉大利,晚上加餐。
4. 知識補充
c_time__date
調用的是
mysql
的
DATE
方法,若覺得中間容易出錯,在邏輯允許情況下可更改字段
同栗,檢視建立時間
c_time
為
2019-3-20
的記錄數目。
In [38]: res = Student.objects.filter(c_time__startswith='2019-03-20')
In [39]: res.count()
Out[39]: 8
In [40]: str(res.query)
Out[40]: 'SELECT `book_student`.`id`, `book_student`.`name`, `book_student`.`age`, `book_student`.`gender`, `book_student`.`c_time`, `book_student`.`college_id` FROM `book_student` WHERE `book_student`.`c_time` LIKE BINARY 2019-03-20%'
或者
In [42]: res = Student.objects.filter(c_time__contains='2019-03-20')
In [43]: res.count()
/home/zdq/.virtualenvs/djfirst/lib/python3.5/site-packages/pymysql/cursors.py:170: Warning: (1292, "Incorrect datetime value: '%2019-03-20%' for column 'c_time' at row 1")
result = self._query(query)
Out[43]: 8
# 哎呀,警告了,看來要慎用
亦或者
In [18]: res = Student.objects.filter(c_time__range=('2019-03-20 00:00:00', '2019
...: -03-21 00:00:00'))
In [19]: str(res.query)
Out[19]: 'SELECT `book_student`.`id`, `book_student`.`name`, `book_student`.`age`, `book_student`.`gender`, `book_student`.`c_time`, `book_student`.`college_id` FROM `book_student` WHERE `book_student`.`c_time` BETWEEN 2019-03-19 16:00:00 AND 2019-03-20 16:00:00'
In [20]: res.count()
Out[20]: 8
- 會發出警告:time zone support is active.RuntimeWarning
- sql 是使用
時間的,不難看出UTC
語句時間區間提前6小時。sql
從不同角度,使用不同的方法,不同方法的優劣這些都是語言的美麗了。
墨染是最棒的
Tuple是最強的
我是最帥的