Python中pymysql处理数据库列表包含毫秒的数据有好办法没?

如题,最近遇到几个链接 mssql 数据库功能, 使用 pymsql 进行 sql 语句拼接。 pymsql 获取的时间直接变成 datetime 类型,毫秒位数比较多,

比如 2018-08-22 12:12:56.2888 我将其转为字符串方法:

先返回时间字符串+"."+毫秒字符串[:3 ] 直接插入 sql 语句报错,sql 查询时间毫秒是三位 如 2018-12-12 23:14:25.200 ,所以做了截取。

总感觉这种方法不合适,有没有比较好的方法。


Python中pymysql处理数据库列表包含毫秒的数据有好办法没?

5 回复

不太清楚你的意思,好像是字符串中小数位数的保留的问题,4 位改成三位,截短。
如果是这样的话,可以是使用 format()字符串格式化方法。

如:
’{0:<23}’.format(‘2018-08-22 12:12:56.2888’)

0 对应这个字符串
:表示格式
<表示左对齐
23 表示字符串保留的长度。

format 的功能比较强大,你可以搜下相关的博文,查具体的用法。


问题分析:
你遇到的是从数据库读取包含毫秒的日期时间数据时,Python的datetime对象可能丢失毫秒精度的问题。这通常是因为数据库驱动(如pymysql)默认将时间字段转换为Python的datetime.datetime对象,而datetime的微秒精度是6位(微秒),但数据库中的毫秒(3位)可能被错误处理或截断。

解决方案:

  1. 检查数据库字段类型:确保数据库中的时间字段类型支持毫秒(如MySQL的DATETIME(3)TIMESTAMP(3))。
  2. 使用pymysql的cursorclass参数:通过pymysql.cursors.DictCursorpymysql.cursors.Cursor直接获取原始字符串,再手动解析。
  3. 自定义转换函数:在查询后对时间字段进行格式化处理。

代码示例:
以下示例通过pymysql连接数据库,并保留毫秒信息:

import pymysql
from datetime import datetime

# 连接数据库
conn = pymysql.connect(
    host='localhost',
    user='user',
    password='password',
    database='test_db',
    charset='utf8mb4'
)

# 使用游标查询,避免自动转换
with conn.cursor(pymysql.cursors.Cursor) as cursor:
    cursor.execute("SELECT your_time_field FROM your_table")
    rows = cursor.fetchall()
    for row in rows:
        # 直接获取字符串格式的时间(包含毫秒)
        time_str = row[0]
        print(f"原始数据:{time_str}")
        # 手动转换为datetime对象(如果需要)
        if '.' in time_str:
            dt_with_ms = datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S.%f')
        else:
            dt_with_ms = datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')
        print(f"解析后:{dt_with_ms}")

conn.close()

关键点:

  • 使用pymysql.cursors.Cursor游标类避免自动类型转换。
  • 通过字符串解析保留毫秒部分(注意数据库返回的格式)。
  • 如果数据库字段是DATETIME(3),查询结果会默认包含毫秒(如'2023-10-01 12:30:45.123')。

一句话建议: 用游标类避免自动转换,手动解析字符串保毫秒。

多谢回复,我具体应用场景是:从数据库 查询修改时间:2018-07-27 11:17:51.327
然后把时间作为数据库查询字段进行再次查询。
当我使用 pymsql 获取到的时间是 “ 2018-08-25 15:32:41.291339 ”
正常数据库时间是 2018-08-25 15:32:41.291
当我直接构建查询语句
····
str1=datetime.datetime.now()
#if len(str1)>23:
# str1=str1[:23]
sql=” select * from A where time1=‘“+str1+”‘“
#sql 语句 select * from A where time1=’ 2018-08-25 15:32:41.291339 ‘
#正确语句 select * from A where time1=’ 2018-08-25 15:32:41.291 ‘
····
此 sql 执行报错 我现在是用条码判断语句直接截取,感觉方式不对,特来问问有啥好办法
····
if len(str1)>23:
str1=str1[:23]
····

if len(str1)>23:
上面这条语句是不能执行的。datetime.datetime 类型的对象,是没有 len 方法的,这么执行你讲得到异常:“TypeError”。

1. 不过你可以把 datetime 对象转化为 str,然后我用切片进行截短。例如 len(str(str1))是可行的,但这样就不太优雅了。

2. 如果是想获得字符串格式的时间,建议:
str1 = datetime.datetime.now().strftime(’%Y-%m-%d %H:%M:%S:%f)
cursor.excute(’ select * from A where time1={}’.format(str1))

这样子是可行的。如果精度要求不高。

如果 str1 你总是想保留后面三位小数,那么比如截取重新生成一个。

#1 更正: 我在 1 楼关于 format 的用法有误{0:23}.format()是针对数字操作的,不能想当然也处理 str

更正如下:
str1 = datetime.datetime.now().strftime(’%Y-%m-%d %H:%M:%S)
cursor.excute(’ select * from A where time1={}’.format(str1))

说明: str1 中的%f 忘了去掉。

没有测试 mysql 是否支持五位数小数%f,理论上是支持的,楼主自行测试一下。

回到顶部