You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:48:22