You need to enable JavaScript to run this app. Discord Bot Python脚本在Ubuntu 20.04 VPS运行报类型错误 Windows端正常
优惠活动
大模型
产品
解决方案
定价
更多

Discord Bot Python脚本在Ubuntu 20.04 VPS运行报类型错误 Windows端正常

问题核心诱因
  • 报错和业务代码逻辑无关,是两个环境的SQLite驱动行为差异,叠加数据库内的历史脏数据共同导致的:
    • SQLite采用动态类型存储机制,哪怕建表时把字段声明为INTEGER类型,也支持存入TEXT形式的数值,驱动会严格按照数据实际的存储类返回对应Python类型,不会强制校验类型一致性。
    • Windows官方Python安装包内置的SQLite核心版本更高,对具备INTEGER列亲和性的字段,读取时会自动将TEXT存储的数值字符串隐式转换为Python int;而Ubuntu 20.04下Python 3.9绑定的SQLite版本严格遵循存储类返回规则,存的是TEXT就直接返回str,不做隐式类型转换。
  • 你在Windows端长期运行时,因为一直用f-string拼接SQL传值,已经在misija.sqlite数据库的userid、laikasmisija列里混入了TEXT类型的数值。本地运行时靠驱动的隐式转换兜底,从来没暴露这个问题,部署到VPS上驱动不再做隐式转换,直接把str类型的值传给Python,才会触发str - int的类型运算报错。
无需全量修改代码的解决方案

完全不需要逐行给所有变量加int()转换,有两种低工作量的方案可选:

  1. 最快适配方案(改几行连接代码即可)
    写一个通用的数据库连接函数,全局注册INTEGER类型的转换规则,让所有数据库连接读出来的数字字段自动转成int,完全复现Windows端的隐式转换行为。只需要把脚本里所有原来手写的sqlite3.connect()语句替换成调用这个函数的代码即可,业务逻辑代码完全不用改动:
    import sqlite3
    from sqlite3 import PARSE_DECLTYPES
    
    def get_db_conn(db_path):
        # 注册INTEGER类型的自动转换规则,不管底层存的是文本还是数值,都转成Python int
        sqlite3.register_converter("INTEGER", lambda value: int(value.decode()) if value else 0)
        conn = sqlite3.connect(db_path, detect_types=PARSE_DECLTYPES)
        return conn
    
    原来的连接代码db=sqlite3.connect('misija.sqlite')替换成db = get_db_conn('misija.sqlite')即可,全脚本改动量不超过10行。
  2. 一劳永逸方案(一次性修复数据库脏数据)
    直接连接VPS上的misija.sqlite数据库,执行一段强制类型转换的SQL,把表内混入的TEXT类型数值统一转成标准INTEGER存储,后续驱动读出来就会直接返回int类型,连代码都不用改:
    -- 修复misijos表内的类型不统一问题
    UPDATE misijos SET laikasmisija = CAST(laikasmisija AS INTEGER);
    UPDATE misijos SET userid = CAST(userid AS INTEGER);
    
    执行完成后,全表的数值字段就和Windows端的预期行为一致了,不会再触发类型错误。

补充说明:你当前所有用f-string拼接SQL的写法本身存在SQL注入风险,后续如果有时间可以逐步替换为参数化查询,从根源上避免混类型存值的问题,但这部分不属于当前报错的必须修改范围。


内容的提问来源于stack exchange,提问作者Kevinas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.06 10:54:05