2013-04-04 209 views
2

我試圖通過python使用sqlalchemy包將記錄插入mysql數據庫。mysql和python日期時間

我具有在MySQL的datetime型已經通過負載表內嵌命令接受下列格式的數據列:

'2013-04-03 00:05:00-05:00' 

注意,這是通過在Python pytz模塊產生。我沒有問題,使用load table inline <file_name>命令通過mysql控制檯加載具有完全相同格式的日期時間戳600,000行。 MySql在加載時接受它們,但我不確定它是否維護時區信息。這對我來說並不重要,因爲我有3個其他列,它們表示我感興趣的其他時區的日期時間。因此,我知道哪一列表示EST/EDT或CST/CDT,並且如果我願意,我可以查詢。我不會在mysql中進行任何時區轉換,因爲我已經有了代表感興趣時區的列。

這是按MySQL的文檔:

The DATETIME type is used for values that contain both date and time parts. MySQL 
retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. The supported 
range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'. 

的東西是pytz模塊提供的日期時間戳,我想插入時區信息。我實際上有4列(EST, UTC, EST/EDT and CST/CDT),所以他們都有他們的時區信息嵌入日期時間戳。

注意我沒有使用自定義INSERT查詢。這是SQLAlchemy的默認方式執行許多插入:

執行插入函數看起來像這樣:

def insert_data(data_2_insert, table_name): 
    # Connect to database using SQLAlchemy's create_engine() 
    engine = create_engine('mysql://blah:[email protected]/db_name') 
    # Metadata is a Table catalog. 
    metadata = MetaData() 
    my_table = Table(table_name, metadata, autoload=True, autoload_with=engine) 
    column_names = tuple(c.name for c in my_table.c) 
    final_data = [dict(zip(column_names, x)) for x in data_2_insert] 
    ins = my_table.insert() 
    conn = engine.connect() 
    conn.execute(ins, final_data) 
    conn.close() 

錯誤消息:

Traceback (most recent call last): 
     File "script.py", line 191, in <module> 
     main() 
     File "script.py", line 39, in main 
     insert_data(file_csv, table_name) 
     File "script.py", line 58, in insert_data 
     conn.execute(ins, final_data) 
     File "/usr/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 824, in execute 
     return Connection.executors[c](self, object, multiparams, params) 
     File "/usr/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 874, in _execute_clauseelement 
     return self.__execute_context(context) 
     File "/usr/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 894, in __execute_context 
     self._cursor_executemany(context.cursor, context.statement, context.parameters, context=context) 
     File "/usr/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 960, in _cursor_executemany 
     self._handle_dbapi_exception(e, statement, parameters, cursor, context) 
     File "/usr/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 931, in _handle_dbapi_exception 
     raise exc.DBAPIError.instance(statement, parameters, e, connection_invalidated=is_disconnect) 
    sqlalchemy.exc.OperationalError: (OperationalError) (1292, "Incorrect datetime value: '2013-04-03 00:05:00-05:00' for column 'rtc_date_est' at row 1") 
+0

最後一部分似乎打破了:'2013-04-03 00:05:00-05:00',那裏不應該有'-05:00',對吧?我猜想在這種情況下,sqlalchemy並沒有做太多的類型檢查。 – Wolph 2013-04-04 22:09:35

+0

最初,我的數據是在EST中。但我需要在其他兩個時區(EST/EDT和CST/CDT)進行這項工作。每次我需要運行日期查詢時,我都不想在sql中執行對話,因爲我會做很多事情。所以它的存儲性能和性能之間存在交易。所以在Python中,我使用日期時間字符串,通過'pytz.timezone('EST')將其分配給EST時區,然後執行3次轉換 - 「US/Eastern」,「US/Central」和'utc'。所以'-05:00'表示它是'EST'。類似地,對於'EST/EDT','+00:00'是'UTC','-04:00','CST/CDT'是'-05:00'。 – codingknob 2013-04-04 22:34:42

+0

'-05:00'擴展名存在於我嘗試插入到mysql的對象中。請注意,mysql不會抱怨,因爲我通過加載表成功。所以這是sqlalchemy的問題。如何在不重寫我的方法的情況下實現我的目標。我感謝你的幫助。 – codingknob 2013-04-04 22:36:32

回答

0

看來,SQLAlchemy的不尊重MySQL DATETIME格式。 SQLAlchemy試圖將一個時區感知格式放入MySQL DATETIME中,該文件不支持基於每行AFAIK的時區。

解決方法是從datetime對象中剝離時區信息。它們轉換成符合你的MySQL默認(UTC,EST,等等)時區後,然後執行以下操作:

date_value = date_value.replace(tzinfo=None) 

其中DATE_VALUE是最終被傳遞給你的SQLAlchemy的對象DateTime對象。