2016-04-18 24 views
7

Tôi đang đọc trong các kiểu dữ liệu khác nhau từ một cơ sở dữ liệu mySQL. Cột thứ năm có kiểu 'DATETIME' trong cơ sở dữ liệu. Tôi sử dụng nó như là entry_date cho một đối tượng 'BloodTraitRecord'.Làm thế nào tôi có thể ngừng python chuyển đổi mySQL DATETIME thành datetime.date khi thời gian là 00:00:00?

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 lớp:

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 

đối tượng DATETIME từ cơ sở dữ liệu giống như thế này trong máy chủ mySQL:

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

Các chức năng mã như dự kiến ​​trừ thời gian trong cơ sở dữ liệu là nửa đêm , giống như vậy:

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

Trong trường hợp đó, và đó là trường hợp duy nhất, tôi nhận được lỗi này khi so sánh entry_date.date của kỷ lục() để datetime.date khác sau này trong các mã:

# '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' 

In ấn record.entry_date khẳng định rằng thuộc tính thời gian đã biến mất trong trường hợp này:

'2014-05-18' 

Tôi có cách khắc phục điều này bằng cách kiểm tra loại đối tượng và chỉ gọi thuộc tính ngày nếu đối tượng là ngày giờ, nhưng tôi tự hỏi nếu có tốt hơn sửa chữa hơn này.

Tôi cũng không hiểu tại sao python chuyển ngay lập tức MySQL DATETIME thành datetime.date khi thời gian DATETIME là 00:00:00.

Cảm ơn sự giúp đỡ của bạn!

+1

Bạn đang nói Python chuyển đổi DATETIME MySQL thành 'datetime.date' nếu giá trị bao gồm nửa đêm, nhưng không phải là khác? Bạn đang sử dụng ORM hoặc trình kết nối nào? Có vẻ như 'mysql.connector', nhưng vui lòng xác nhận trong câu hỏi. – ChrisP

+0

Tất cả điều đó là chính xác. Đang cập nhật câu hỏi. – Dylan

+0

I * không thể * sao chép vấn đề với phiên bản 'mysql.connector' 2.1.3 và Python 3.5 chạy trên OSX với máy chủ MySQL 5.6.24 cục bộ. Bạn đang chạy phiên bản nào? – ChrisP

Trả lời

1

Tôi đảm bảo rằng bạn có đối tượng datetime ngay khi bạn giải nén nó khỏi cơ sở dữ liệu. Sau đó, bạn không phải thực hiện bất kỳ séc nào trong tương lai. Vì vậy, bạn có thể nói:

chỉ là một chút mã bổ sung và cũng có lợi thế là nếu truy vấn của bạn thay đổi và bạn không cập nhật đúng mã sau khi gặp lỗi loại ngay lập tức. Dưới đây là một thực hiện ví dụ:

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) 

Demo:

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

Output:

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 

Nhưng tôi cảm thấy bạn không muốn phải làm điều này, vì vậy tôi sẽ làm dịu nó như sau:

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

Bây giờ bạn c ode có thể được rút ngắn thành:

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

và bạn không phải nhớ làm bất cứ điều gì.

Các vấn đề liên quan