SQLite3存储时间后调用问题:Python datetime类型转换错误
解决SQLite存储时间后与Python时间对象对比的问题
问题根源
SQLite没有原生时间类型,TIME字段实际存储的是**HH:MM:SS格式的字符串**。你直接用查询到的字符串和datetime.now().time()返回的datetime.time对象对比,不仅无法匹配,还因为错误调用Python内置time()函数(该函数需要整数参数)触发TypeError。
解决步骤
1. 规范时间存储格式
存储时间时,要么用SQLite的time()函数生成标准格式字符串,要么直接插入符合HH:MM:SS的字符串,同时用参数化查询避免SQL注入:
# 方式1:用SQLite time()函数生成时间 cursor.execute("INSERT INTO guildData (guild_id, time) VALUES (?, time(21, 0, 0))", (guild.id,)) # 方式2:直接插入标准格式字符串 cursor.execute("INSERT INTO guildData (guild_id, time) VALUES (?, ?)", (guild.id, "21:00:00")) db.commit()
2. 读取时转换时间类型
查询到字符串后,用datetime.strptime解析为datetime.time对象,再和当前时间对比。
3. 优化代码逻辑
- 避免循环内重复创建数据库连接,提升效率
- 单个服务器对应一条时间记录,用
fetchone()替代fetchall()更合理
修改后的完整代码
import datetime import sqlite3 from discord.ext import tasks @tasks.loop(seconds=1) async def testing(): # 单次连接数据库,循环所有服务器 db = sqlite3.connect('aDatabase.db') cursor = db.cursor() current_time = datetime.datetime.now().time() for guild in bot.guilds: # 参数化查询安全获取服务器对应时间 cursor.execute("SELECT time FROM guildData WHERE guild_id = ?", (guild.id,)) record = cursor.fetchone() if record: # 字符串转time对象 stored_time = datetime.datetime.strptime(record[0], "%H:%M:%S").time() # 时间匹配时执行推送 if current_time == stored_time: await guild.system_channel.send("定时推送消息") db.close()
额外优化建议
- 若需求是每小时检查一次,可将循环间隔改为
seconds=3600,减少无效执行 - 也可以直接用SQL完成时间对比,减少Python端处理:
cursor.execute("SELECT 1 FROM guildData WHERE guild_id = ? AND time = strftime('%H:%M:%S', datetime('now'))", (guild.id,)) if cursor.fetchone(): # 执行推送操作
内容的提问来源于stack exchange,提问作者Do0ks
相关产品推荐
相关产品推荐

