Python sqlite3查询含DATE字段表时出现int() base 10无效字面量错误
问题原因
你的报错根源是字段声明类型和实际存储的数据格式不匹配:
- 建表时
collection_date字段声明的是DATE类型,该类型在Python sqlite3的PARSE_DECLTYPES规则下,只会解析YYYY-MM-DD格式的纯日期字符串,会调用convert_date方法按-分割后转成datetime.date对象 - 你实际存储的是带时分秒的
datetime对象,写入SQLite后会变成YYYY-MM-DD HH:MM:SS格式的字符串,用-分割后最后一段会变成类似31 08:00:00的内容,无法直接转成整数,因此抛出ValueError。你找不到含16 08:00:00的完整内容,是因为报错里的内容是日期字符串按-分割后的第三段片段,原完整日期为XXXX-XX-16 08:00:00 - DB Browser for SQLite没有类型强转逻辑,所以能正常返回字符串格式的结果,不会触发报错。
解决方案
你可以根据业务需求选任意一种:
方案1:修改字段类型为DATETIME
如果需要保留时分秒信息,把建表语句里的collection_date DATE NOT NULL改成collection_date DATETIME NOT NULL即可:
CREATE TABLE rates ( id TEXT NOT NULL, pc INTEGER, collection_date DATETIME NOT NULL, metercount INTEGER NOT NULL, rate REAL )
sqlite3遇到DATETIME声明类型时会自动调用convert_timestamp方法,正确解析带时分秒的日期字符串为Python datetime对象。如果是存量数据,直接执行下面的语句迁移数据即可:
ALTER TABLE rates RENAME COLUMN collection_date TO collection_date_old; ALTER TABLE rates ADD COLUMN collection_date DATETIME NOT NULL; UPDATE rates SET collection_date = collection_date_old;
方案2:查询时显式转换日期格式
如果不需要修改表结构,也可以在查询时把collection_date转成纯日期格式:
dcdata = db.execute("select id, pc, date(collection_date) as collection_date, metercount, rate from rates where id = ?", (dc,)).fetchall()
date()函数会把带时分秒的日期截断为YYYY-MM-DD格式,匹配DATE类型的解析规则。
方案3:自定义DATE类型转换器
如果既要保留字段的DATE声明,又要兼容带时分秒的存储数据,可以注册自定义的DATE类型转换器:
import sqlite3 from datetime import datetime def custom_convert_date(val): # 先截断空格后面的时分秒部分 val = val.split(b' ')[0] return datetime.date(*map(int, val.split(b"-"))) # 注册转换器,覆盖默认的DATE转换逻辑 sqlite3.register_converter("DATE", custom_convert_date)
把这段代码加到你的Flask应用初始化逻辑里即可。
内容的提问来源于stack exchange,提问作者Jay Christnach
相关产品推荐
相关产品推荐

