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处理数据库列表包含毫秒的数据有好办法没?
不太清楚你的意思,好像是字符串中小数位数的保留的问题,4 位改成三位,截短。
如果是这样的话,可以是使用 format()字符串格式化方法。
如:
’{0:<23}’.format(‘2018-08-22 12:12:56.2888’)
0 对应这个字符串
:表示格式
<表示左对齐
23 表示字符串保留的长度。
format 的功能比较强大,你可以搜下相关的博文,查具体的用法。
问题分析:
你遇到的是从数据库读取包含毫秒的日期时间数据时,Python的datetime对象可能丢失毫秒精度的问题。这通常是因为数据库驱动(如pymysql)默认将时间字段转换为Python的datetime.datetime对象,而datetime的微秒精度是6位(微秒),但数据库中的毫秒(3位)可能被错误处理或截断。
解决方案:
- 检查数据库字段类型:确保数据库中的时间字段类型支持毫秒(如MySQL的
DATETIME(3)、TIMESTAMP(3))。 - 使用pymysql的
cursorclass参数:通过pymysql.cursors.DictCursor或pymysql.cursors.Cursor直接获取原始字符串,再手动解析。 - 自定义转换函数:在查询后对时间字段进行格式化处理。
代码示例:
以下示例通过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,理论上是支持的,楼主自行测试一下。

