2016-04-18 5 views
7

私は、mySQLデータベースからさまざまなデータ型を読み込んでいます。 5番目の列は、データベースに '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クラス:MySQLサーバでは、このようなデータベースを見てから

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オブジェクト:

'2008-11-14 13:28: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' 

私は、オブジェクトの種類を確認し、そのオブジェクトが日時の場合にのみ、日付属性を呼び出すことによってこの問題を解決する方法を持っていますが、存在する場合、私は思ったんだけどこれ以上の修正。

また、DATETIMEの時刻が00:00:00の場合、PythonがMySQL DATETIMEをdatetime.dateに変換する理由を理解できません。

ありがとうございました!

+1

値が真夜中を含む場合、PythonはMySQL DATETIMEを 'datetime.date'に変換しますが、それ以外の場合はそうではありませんか?どのORMまたはコネクタを使用していますか? 'mysql.connector'のように見えますが、質問で確認してください。 – ChrisP

+0

それはすべて正しいです。質問を更新する。 – Dylan

+0

ローカルMySQL 5.6.24サーバでOSX上で実行されているmysql.connectorのバージョン2.1.3とPython 3.5では問題を再現できません。実行しているバージョンは何ですか? – ChrisP

答えて

1

データベースからオブジェクトを抽出するとすぐに、datetimeオブジェクトがあることを確認します。それからあなたは将来何らかの小切手をする必要はありません。だからあなたが言うことができる:

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)) 

これは覚えておく必要はありません。

関連する問題