SqlAlchemy mysql 毫秒或微秒精度

SqlAlchemy mysql millisecond or microsecond precision

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

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

2015-04-17 16:31:12.804444

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

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 插入语句。该语句确实包含小数时间值。但是,在执行时,该值会四舍五入。当我对 table 进行描述时,我注意到日期时间类型只是 datetime 而实际上应该是 datetime(6)

我正在使用 SA 模型生成数据库本身,该模型明确声明了 Column(DATETIME(6))Base.metadata.create_all(self.db, checkfirst=True) ,所以我不明白为什么 (6) 没有以实际的 table 结构。我想我很快就会弄清楚,我会 post 更新。

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

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

"MySQL 5.6.4 and up expands fractional seconds support for TIME, DATETIME, and TIMESTAMP values, with up to microseconds (6 digits) precision"

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

这似乎是 MySQLdb 的未解决问题,而不是 MySQL 或 SQLAlchemy。

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

您可以尝试使用另一个 MySQL 驱动程序库 -- 检查 SQLAlchemy documentation 支持的选项 -- 或者您可以尝试打开问题中建议的 monkeypatch。

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

dateCreated = Column(DATETIME(fsp=6)) 

感谢其他回复的人。它帮助指导我的调查,最终绊倒了这个深奥且非常混乱的区别。

为了在 MySQL 中强制使用小数秒精度,同时保持其他引擎的默认值,您可以修改 SQLAlchemy 为 MySQL.[=14= 编译 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])