SqlAlchemy mysql毫秒或微秒精度

时间:2015-04-17 23:34:13

标签: python mysql datetime sqlalchemy milliseconds

我一直在冒险试图让我的数据库中的小数时间分辨率正常工作。我使用python方法datetime.now()来创建日期对象。然后,我将这些对象存储在一个字段中,该字段映射到来自SqlAlchemy库的COLUMN(DATETIME(9))。最初,我收到的错误是我的数据被截断了。这是因为我使用的是mysql 5.5。我已经更新到5.6.19并且不再获得数据截断错误。

但是,数据库实际上仍然不包含小数时间条目。例如,以下是实例化datetime.now()对象时的值:

2015-04-17 16:31:12.804444

以上就是我所期待的。内存中的对象具有微秒分辨率。现在,在将它保存到mysql数据库之后,如果我打开mysql命令行客户端并使用select语句返回行,我会看到以下值:

2015-04-17 16:31:13

显然,该值将四舍五入到最接近的秒。这很糟糕,我不知道是什么造成的!

如果它是相关的,我使用mysql-connector-python == 2.0.3

更新: 我也尝试使用COLUMN(DATETIME(6)),但也有同样的行为。

如果信息相关,我在下面包括模型:

class User(Base):
        __tablename__ = 'Users'

        uid = Column(INT, primary_key=True, autoincrement=True)
        dateCreated = Column(DATETIME(6))

        def __init__(self, *args, **kwargs):
                super(user, self).__init__(*args, **kwargs)
                self.dateCreated = datetime.now()

更新: 佩德罗的建议并不是问题所在,尽管它确实帮助我取得了进步,非常感谢。我尝试单步执行sql连接器中的代码,直到我进入mysql insert语句。该陈述确实包含小数时间值。但是,执行时,该值将四舍五入。当我在桌面上进行描述时,我注意到日期时间类型就是datetime,它应该是datetime(6)

我使用SA模型自行生成数据库,SA模型明确声明Column(DATETIME(6))Base.metadata.create_all(self.db, checkfirst=True),所以我不明白为什么(6)不是'结束于实际的表结构。我想我很快就会弄明白,我会在发布时发布更新。

更新: DATETIME的构造函数不接受字段长度规范。时区只需要一个参数。我不清楚如何指定日期时间字段的长度,因为对于类似varchar的类型,只需将其传递给构造函数。潜水继续。

4 个答案:

答案 0 :(得分:17)

我遇到的问题是库存SqlAlchemy DATETIME类不能使用mysql要求将(6)值传递给构造函数以表示小数时间值。相反,需要使用sqlalchemy.dialects.mysql.DATETIME类。此类允许使用fsp参数(小数秒参数)。因此,列声明实际上应该如下所示:

dateCreated = Column(DATETIME(fsp=6)) 

感谢那些回复的人。它帮助指导我的调查最终绊倒了这种深奥和非常混乱的区别。

答案 1 :(得分:1)

这似乎是MySQLdb的一个开放问题,而不是MySQL或SQLAlchemy。

http://sourceforge.net/p/mysql-python/feature-requests/24/

您可以尝试使用其他MySQL驱动程序库 - 检查SQLAlchemy documentation是否支持选项 - 或者您可以尝试在公开问题中建议的monkeypatch。

答案 2 :(得分:0)

根据MySQL documentation,它仅支持最多6位(微秒)的精度:

" MySQL 5.6.4及更高版本扩展了对TIME,DATETIME和TIMESTAMP值的小数秒支持,精度高达微秒(6位)"

我不确定,但指定9位可能会将列恢复为较小的默认精度。

答案 3 :(得分:0)

为了在MySQL中强制使用小数秒精度,同时在其他引擎上保留默认值,您可以修改SQLAlchemy如何为MySQL编译DateTime类型。

from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime
from sqlalchemy.dialects.mysql import DATETIME

@compiles(DateTime, "mysql")
def compile_datetime_mysql(type_, compiler, **kw):
     return "DATETIME(6)"

基本上,这是告诉sql alchemy仅针对mysql用自定义类型编译DateTime,在我们的示例中返回DATETIME(6),其中值为6的参数为fsp(分数秒精度[来自MySQL 5.6.4])