2016-04-18 38 views
7

我正在閱讀從mySQL數據庫的各種數據類型。第五列在數據庫中有'DATETIME'類型。我使用它作爲'BloodTraitRecord'對象的entry_date。當時間是00:00:00時,如何停止python將mySQL DATETIME轉換爲datetime.date?

import mysql.connector 
from datetime import timedelta 
from datetime import datetime 

show_DB = """select RUID, test_sname, test_value, units, ref_range, entry_date from %s 
      where RUID=%%s and test_sname=%%s order by RUID, 
      test_sname, entry_date Limit 5;""" % (tableToUse,) 

cursor.execute(show_DB, (ruid, traitPair[0])) 
resultsForOneTrait = cursor.fetchall() 

for result in resultsForOneTrait: 
    ruid = result[0] 
    s_name = result[1].decode("UTF-8") 
    value = result[2] 
    units = result[3].decode("UTF-8") 
    ref_range = result[4].decode("UTF-8") 

    # Need assistance here 
    entryDate = result[5] 

    record = BloodTraitRecord(ruid, s_name, value, units, ref_range, entryDate) 

BloodTraitRecord類:從數據庫

class BloodTraitRecord: 

def __init__(self, ruid, test_sname, test_value, units, ref_range, entry_date): 
    self.RUID = ruid 
    self.test_sname = test_sname  
    self.test_value = test_value 
    self.units = units    
    self.ref_range = ref_range 


    self.entry_date = entry_date 

DATETIME物體看起來像這樣在MySQL服務器:

'2008-11-14 13:28:00' 

預期,除非在數據庫中的時間是午夜的代碼功能,如下所示:

'2014-05-18 00:00:00' 

在這種情況下,只有這種情況下,我記錄的entry_date.date()在後面的代碼比較其他datetime.date時出現此錯誤:

# 'cancerCutoff' is consistently a datetime.date 
cancerCutoff = firstCancerAnemiaCodeDate[ruidkey] - timedelta(days=180) 
if cancerCutoff < record.entry_date.date(): 
AttributeError: 'datetime.date' object has no attribute 'date' 

印刷record.entry_date確認時間屬性沒有了這種情況:

'2014-05-18' 

我有辦法通過檢查對象的類型,只調用如果對象是一個日期時間日期屬性來解決這個問題,但我想知道如果有一個比這更好的解決方法。

我也不明白爲什麼python會在DATETIME時間爲00:00:00時立即將MySQL DATETIME轉換爲datetime.date。

感謝您的幫助!

+1

你是說如果Python的值包含午夜,Python會將MySQL DATETIME轉換爲'datetime.date',但否則不會?你使用的是什麼ORM或連接器?看起來像'mysql.connector',但請在問題中確認。 – ChrisP

+0

所有這些都是正確的。更新問題。 – Dylan

+0

我*不能*通過在本地MySQL 5.6.24服務器上運行的mysql.connector版本2.1.3和Python 3.5複製問題。你正在運行什麼版本? – ChrisP

回答

1

我會確保你有一個日期時間對象,只要你從數據庫中提取它。那麼你將來不必做任何檢查。所以,你可以說:

entryDate = ensure_datetime(result[5]) 

這是隻有一點點額外的代碼,並且還具有以下優點:如果您的查詢的變化和不正確更新代碼後,會立即去追類型錯誤。下面是一個示例實現:

from datetime import datetime, date 

# Thanks to http://stackoverflow.com/a/1937636/2482744 
def date_to_datetime(d): 
    return datetime.combine(d, datetime.min.time()) 

def ensure_datetime(d): 
    if isinstance(d, datetime): 
     return d 
    elif isinstance(d, date): 
     return date_to_datetime(d) 
    else: 
     raise TypeError('%s is neither a date nor a datetime' % d) 

演示:

for x in [date(2016, 5, 12), 
      datetime(2016, 5, 12, 9, 32, 57, 345), 
      'a string']: 
    print(ensure_datetime(x)) 

輸出:

2016-05-12 00:00:00 
2016-05-12 09:32:57.000345 
Traceback (most recent call last): 
    File "/Users/alexhall/Dropbox/python/sandbox/sandbox.py", line 14, in <module> 
    print(ensure_datetime(x)) 
    File "/Users/alexhall/Dropbox/python/sandbox/sandbox.py", line 9, in ensure_datetime 
    raise TypeError('%s is neither a date nor a datetime' % d) 
TypeError: a string is neither a date nor a datetime 

但我感到你不希望有這樣做,所以我將它變甜如下:

def clean_types(row): 
    new_row = [] 
    for item in row: 
     if isinstance(item, date) and not isinstance(item, datetime): 
      item = date_to_datetime(item) 
     elif isinstance(item, str): 
      item = item.decode("UTF-8") 
     new_row.append(item) 
    return new_row 

# Demo 
print(clean_types([3, 'abc', u'def', date.today(), datetime.now()])) 
# [3, u'abc', u'def', datetime.datetime(2016, 5, 12, 0, 0), datetime.datetime(2016, 5, 12, 17, 22, 7, 519604)] 

現在你的c Ode可縮寫爲:

for result in resultsForOneTrait: 
    record = BloodTraitRecord(*clean_types(result)) 

而且您不必記得做任何事情。

相關問題