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

Python操作SQLite报错:int()无效字面量,求代码排查帮助

解决Python操作SQLite时的ValueError及代码问题

首先,你的核心报错ValueError: invalid literal for int() with base 10: "SELECT AVG(rssi)..."是因为你把SQL查询语句的字符串直接赋值给了numpy数组元素,而不是执行这个查询并获取计算后的平均值。下面我会一步步拆解你的代码问题,并给出修正方案:

主要问题分析

1. 未执行SQL查询就赋值

你当前的代码只是构造了query这个字符串,并没有让数据库执行它,就直接把字符串塞给了avg[0]——数组期望的是数值,而你给了一段SQL文本,自然会报错。你需要执行查询,然后提取返回的平均值。

2. SQL拼接错误(参数未正确传递)

用format('dev', 'mac', ...)拼接SQL时,你传入的是字符串'dev'和'mac',而不是循环中的变量dev和mac的值。这会导致SQL语句变成dev LIKE 'dev',而不是匹配实际的设备编号和MAC地址,完全不符合你的需求。而且这种拼接方式存在SQL注入风险,应该用SQLite的参数化查询(用?占位符)。

3. 游标只能遍历一次

posconn.execute("SELECT distinct(mac) FROM unitedata;")返回的游标对象只能被遍历一次,你直接放在for mac in uniqmac:里,第一次循环后游标就空了,后续循环不会有数据。需要先把结果转换成列表保存。

4. executemany使用错误

executemany是用来批量插入多条数据的,而你每次只准备了一条数据,应该用execute;而且store是一个列表,并没有fetchall()方法,这会导致另一个错误。

5. 数据库连接与资源管理问题

你没有正确关闭游标和连接,最好使用with语句来自动管理数据库连接,避免资源泄漏。另外,close(avgcon)的写法错误,应该是avgcon.close()。

6. 变量名冲突

time是Python的内置模块名称,不要用它作为变量名,否则会覆盖内置模块,导致后续可能出现奇怪的问题。

修正后的代码

import sqlfunktion
import numpy as np
from sqlite3 import connect
from datetime import datetime
from time import mktime

def avgrssi(date): # date on format as "YYYY,mm,dd"
    # 用with语句管理数据库连接,自动关闭
    with sqlfunktion.opendb("totdata") as posconn:
        # 先把distinct mac的结果存成列表,避免游标只能遍历一次
        uniqmac_cursor = posconn.execute("SELECT distinct(mac) FROM unitedata;")
        uniqmac_list = [row[0] for row in uniqmac_cursor.fetchall()]
        
        unixnr_cursor = posconn.execute("SELECT MIN(time) FROM unitedata;")
        unix = unixnr_cursor.fetchone()[0]
        devices = [146, 147, 148, 149]

    # 处理平均数据的数据库连接
    with sqlfunktion.createdb("avgdata") as avgcon:
        # 先检查表是否存在,避免重复创建报错
        avgcon.execute("""
            CREATE TABLE IF NOT EXISTS avgrs(
                time INTEGER, 
                mac TEXT, 
                avg1 REAL, 
                avg2 REAL, 
                avg3 REAL, 
                avg4 REAL
            );
        """)

        # 遍历时间区间
        for dtime in range(10 + int(unix/60), 23*60 + int(unix/60)):
            for mac in uniqmac_list:
                avg = [0.0, 0.0, 0.0, 0.0]  # 用普通列表即可,numpy不是必须的
                for idx, dev in enumerate(devices):
                    # 使用参数化查询,避免SQL注入和拼接错误
                    query = """
                        SELECT AVG(rssi) FROM unitedata 
                        WHERE dev = ? AND mac = ? AND time <= ? AND time >= ?;
                    """
                    # 执行查询并获取结果
                    cursor = avgcon.execute(query, (dev, mac, dtime*60+15, dtime*60-15))
                    result = cursor.fetchone()[0]
                    # 如果有结果(不是None),就赋值,否则保持0.0
                    if result is not None:
                        avg[idx] = float(result)
                
                # 插入单条数据,用execute而不是executemany
                current_time = dtime * 60  # 这里用明确的时间变量,避免和内置time冲突
                avgcon.execute("""
                    INSERT INTO avgrs(time, mac, avg1, avg2, avg3, avg4) 
                    VALUES (?, ?, ?, ?, ?, ?);
                """, (current_time, mac, avg[0], avg[1], avg[2], avg[3]))
        
        # 获取所有平均数据
        avgtab_cursor = avgcon.execute("SELECT time, mac, avg1, avg2, avg3, avg4 FROM avgrs;")
        avgtab = avgtab_cursor.fetchall()

    return avgtab

if __name__ == '__main__':
    dato = (2018,1,5)
    avgrssi(dato)

关键修改说明

  • 执行SQL查询并获取结果:对每个设备构造参数化查询,执行后用fetchone()[0]获取平均值,转成浮点数后赋值给列表元素。
  • 参数化SQL:用?作为占位符,把变量作为元组传给execute,既避免了拼接错误,又防止SQL注入。
  • 保存MAC列表:把游标结果转换成列表,确保可以多次遍历。
  • 修改表结构:把原来的avg列拆分成四个列(对应四个设备),这样更符合数据存储逻辑,也避免存数组的麻烦。
  • 用with管理连接:自动处理连接的打开和关闭,避免资源泄漏。
  • 替换冲突变量名:把time变量改成current_time,避免覆盖内置模块。
  • 检查表是否存在:用CREATE TABLE IF NOT EXISTS,避免重复运行时报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:26:28