Python操作SQLite报IntegrityError数据类型不匹配错误修复
SQLite3
IntegrityError: datatype mismatch 错误原因与修复方案 错误根因
- 旧表结构冲突:你使用了
CREATE TABLE IF NOT EXISTS语法,若脚本运行目录下已存在历史测试生成的Bank_Users.db文件,且其中bank表结构和当前代码定义不一致(比如测试时曾将pin设为INTEGER PRIMARY KEY自增列、字段顺序写反、username字段类型设为INTEGER),代码不会重建或更新表结构。插入数据时,字符串类型的用户名被传入整数类型的主键字段,就会触发数据类型不匹配的完整性错误。 - 重复插入主键冲突:测试用户的INSERT语句写死在脚本中,每次运行都会重复执行。首次运行插入成功后,后续运行重复插入相同
username(主键)会触发约束报错,部分SQLite版本下类型隐式转换失败时也会抛出datatype mismatch类错误。 - 结果遍历逻辑存在隐性bug:你定义的表仅包含
username、pin2个字段,返回结果元组长度为2,但循环打印时访问了不存在的result[2]索引,且直接将整数类型的pin值与字符串用+拼接,会触发Python层面的类型错误,调试时若误将拼接内容传入SQL执行语句,也会触发数据库端的类型错误。 - 缺失事务提交:现有代码执行插入后没有调用
connection.commit(),数据不会真正持久化到数据库文件,多次运行时事务回滚也可能引发异常。
分步修复方案
- 清理历史错误数据:直接删除脚本目录下的
Bank_Users.db文件,移除结构错误的旧表。 - 修正数据插入逻辑,使用参数化查询避免类型问题与重复插入:
# 创建表后执行,替换原有硬编码INSERT语句 test_users = [ ('Kailas Kurup', 7620), ('Bethany Watkins', 4638), ('John Hammond', 3482), ('Melissa Rodriguez', 3493), ('Gopalakrishnan Nair', 9891) ] # INSERT OR IGNORE 遇到已存在主键时自动跳过,避免重复插入报错 # 用?做参数占位,自动处理类型匹配,避免SQL注入 cursor.executemany("INSERT OR IGNORE INTO bank (username, pin) VALUES (?, ?)", test_users) connection.commit() # 提交事务,持久化插入结果 - 修正结果打印逻辑,修复索引越界与类型拼接问题:
# Get Results / Querying Database cursor.execute("SELECT username, pin FROM bank") results = cursor.fetchall() print(results) # Format Results print("username\t\t\tpin") print("-------\t\t\t--------") for username, pin in results: # 直接解包字段,避免索引写错 print(f"{username}\t\t{pin}") - 补充资源释放逻辑:所有数据库操作完成后,调用
cursor.close()、connection.close()释放资源,避免数据库锁定问题。
后续Tkinter GUI阶段提前优化建议
- 现有第一阶段逻辑中余额是所有用户共用的全局变量,后续需要在
bank表新增balance REAL字段,为每个用户单独存储余额,不要使用全局共享的余额变量。 - 读取
current_balance.txt时建议使用with open()上下文管理器,自动处理文件关闭,避免文件句柄泄漏,同时增加文件不存在的异常捕获逻辑。 - PIN属于敏感验证信息,不要明文存储,后续可增加哈希加盐处理后再存入数据库。
内容的提问来源于stack exchange,提问作者kkurup
相关产品推荐
相关产品推荐

