2013-04-04 4 views
2

Я пытаюсь вставить записи в базу данных mysql через python с использованием пакета sqlalchemy.mysql и python datetime

У меня есть столбцы, которые datetime типа в MySQL, которые уже приняты данные в следующем формате с помощью команды Таблица инлайн нагрузки:

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

ПримечаниеЭтот производится с помощью pytz модуля в Python. У меня не было проблем с загрузкой 600 000 строк с метками datetime с точно таким же форматом через консоль mysql с помощью команды load table inline <file_name>. MySql принимает их при загрузке, но я не уверен, поддерживает ли он информацию о часовом поясе. Это действительно не имеет значения для меня, потому что у меня есть еще три столбца, которые представляют даты в других часовых поясах, которые меня интересуют. Поэтому я знаю, какой столбец представляет 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

+0

Первоначально мои данные находятся в 'EST'. Но мне нужно это время в двух других часовых поясах '(EST/EDT и CST/CDT'). Я не хочу выполнять беседу в sql каждый раз, когда мне нужно запустить запрос на дату, потому что я буду делать это много. Таким образом, его хранение против производительности компромисс. Поэтому в python я беру строку datetime, назначая ее в часовой пояс EST через 'pytz.timezone ('EST')', а затем выполняю 3 преобразования - в 'US/Eastern'',' US/Central'' и 'utc'. Таким образом, '' -05: 00'' должен показать, что это 'EST'. Аналогично, '+00: 00' является' UTC', '-04: 00' для' EST/EDT' и '-05: 00' для' CST/CDT'. – codingknob

+0

расширение '-05: 00' присутствует в объекте, который я пытаюсь вставить в mysql. Обратите внимание: mysql не жалуется на это, потому что я успешно прошел через таблицу загрузки. Так что это проблема с sqlalchemy. Как я могу достичь своей цели, не переписывая свой подход. Я благодарю вас за вашу помощь. – codingknob

ответ

0

Оказывается, что SQLAlchemy не уважает формат MySQL DATETIME. SQLAlchemy пытается поместить формат, соответствующий часовому поясу, в MySQL DATETIME, который не поддерживает часовой пояс для каждой строки AFAIK.

Решение состоит в том, чтобы удалить информацию о часовом поясе от ваших объектов datetime. После преобразования их в часовой пояс, совпадающий с MySQL по умолчанию (UTC, EST, что угодно), то сделайте следующее:

date_value = date_value.replace(tzinfo=None) 

где date_value является объектом DateTime, который заканчивает тем, что передается к объекту SQLAlchemy.

Смежные вопросы