Невозможно сохранить datetime.datetime.max с помощью SQLAlchemy==0.8.1 с драйвером mysql-python==1.2.4
Я заметил изменение в поведении для хранения datetime.datetime.max через SQLAlchemy==SQLAlchemy==0.8.1
и собирается из mysql-python==1.2.3
в mysql-python==1.2.4
, Меняя драйвер только с 1.2.3 на 1.2.4, я перешел от возможности сохранить его к невозможности сохранить его.
Куда мне обратиться за помощью в этом вопросе? SQLAlchemy или mysql-python? Это ожидаемое поведение или ошибка, или у меня плохая настройка? Я боюсь, что подобное изменение сломает множество систем.
Это моя настройка SQLAlchemy:
from sqlalchemy import create_engine, Integer, DateTime, Column
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime
engine = create_engine('mysql://root@localhost/test_database', echo=True)
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
age = Column(DateTime, default=datetime.max)
Base.metadata.create_all(engine)
session = sessionmaker(bind=engine)()
u = User()
session.add(u)
session.commit()
У меня также есть virtualenv под названием тест. Это то, что происходит, когда я запускаю код выше.
(test)➜ ~ pip install MySQL-python==1.2.3
(test)➜ ~ python test.py
2013-06-26 10:29:18,885 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2013-06-26 10:29:18,885 INFO sqlalchemy.engine.base.Engine ()
2013-06-26 10:29:18,887 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'character_set%%'
2013-06-26 10:29:18,887 INFO sqlalchemy.engine.base.Engine ()
2013-06-26 10:29:18,891 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2013-06-26 10:29:18,891 INFO sqlalchemy.engine.base.Engine ()
2013-06-26 10:29:18,896 INFO sqlalchemy.engine.base.Engine DESCRIBE `users`
2013-06-26 10:29:18,896 INFO sqlalchemy.engine.base.Engine ()
2013-06-26 10:29:18,904 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2013-06-26 10:29:18,905 INFO sqlalchemy.engine.base.Engine INSERT INTO users (age) VALUES (%s)
2013-06-26 10:29:18,905 INFO sqlalchemy.engine.base.Engine (datetime.datetime(9999, 12, 31, 23, 59, 59, 999999),)
2013-06-26 10:29:18,908 INFO sqlalchemy.engine.base.Engine COMMIT
И база данных (test_database) выглядит так:
mysql> select * from users;
+----+---------------------+
| id | age |
+----+---------------------+
| 1 | 9999-12-31 23:59:59 |
+----+---------------------+
1 row in set (0.00 sec)
Это мой ожидаемый результат, так что ничего странного здесь.
Однако, просто переключив драйвер на mysql-python==1.2.4, я получаю этот результат.
(test)➜ ~ pip install MySQL-python==1.2.4
(test)➜ ~ python test.py
2013-06-26 10:33:39,544 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2013-06-26 10:33:39,544 INFO sqlalchemy.engine.base.Engine ()
2013-06-26 10:33:39,546 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'character_set%%'
2013-06-26 10:33:39,546 INFO sqlalchemy.engine.base.Engine ()
2013-06-26 10:33:39,546 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2013-06-26 10:33:39,546 INFO sqlalchemy.engine.base.Engine ()
2013-06-26 10:33:39,547 INFO sqlalchemy.engine.base.Engine DESCRIBE `users`
2013-06-26 10:33:39,547 INFO sqlalchemy.engine.base.Engine ()
2013-06-26 10:33:39,551 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2013-06-26 10:33:39,552 INFO sqlalchemy.engine.base.Engine INSERT INTO users (age) VALUES (%s)
2013-06-26 10:33:39,552 INFO sqlalchemy.engine.base.Engine (datetime.datetime(9999, 12, 31, 23, 59, 59, 999999),)
/Users/pelle/.virtualenvs/test/lib/python2.7/site-packages/sqlalchemy/engine/default.py:324: Warning: Datetime function: datetime field overflow
cursor.execute(statement, parameters)
/Users/pelle/.virtualenvs/test/lib/python2.7/site-packages/sqlalchemy/engine/default.py:324: Warning: Out of range value for column 'age' at row 1
cursor.execute(statement, parameters)
2013-06-26 10:33:39,553 INFO sqlalchemy.engine.base.Engine COMMIT
И база данных выглядит так.
mysql> select * from users;
+----+---------------------+
| id | age |
+----+---------------------+
| 1 | 0000-00-00 00:00:00 |
+----+---------------------+
1 row in set (0.00 sec)
Так что теперь внезапно я получаю предупреждение Warning: Datetime function: datetime field overflow
и я в конечном итоге обнуляемое значение в моей базе данных.
1 ответ
Это сообщаемая ошибка в новой версии сервера MySQL (5.6.X), связанная с округлением в доли секунды.
Смотрите эту ссылку для получения дополнительной информации: http://bugs.mysql.com/bug.php?id=68760
Способ обойти это, чтобы округлить миллисекунды.