Python+sqlite3如何比对新旧查询值判断表字段是否变更
实现方案
核心逻辑很简单:每次读取到新的SIM卡ICCID值后,先取出数据库里存储的上一条历史值,直接比对两个值是否相等,就能判断字段是否发生变更。不建议把数据库比对逻辑硬塞进get_sim_number()这个纯硬件读取函数里,拆分职责后续维护更方便。
另外先修正你原有代码的两个明显bug:
get_sim_number()函数最后返回的变量名拼写错误,respone应为response,否则运行会直接抛出变量不存在的异常- 建表用的表名是
DataTable,插入数据用的表名是NumData,表名不统一,运行会报表不存在的错误
完整可运行代码
import serial import sqlite3 # 初始化数据库连接,按实际路径修改库文件地址 conn = sqlite3.connect('sim_record.db') db_cursor = conn.cursor() # 替换为你实际使用的串口号 SERIAL_PORT = "COM3" def get_sim_number(): """仅负责读取SIM卡ICCID,不掺杂数据库逻辑,保持功能单一""" iccid = None try: ser = serial.Serial(port=SERIAL_PORT, baudrate=115200, timeout=1) ser.write(b"AT+ICCID\r\n") resp = ser.readline().decode('utf-8') iccid = resp.strip().replace("+ICCID: ", "") ser.close() print(f"当前读取ICCID:{iccid}") except Exception as e: print(f"读取SIM卡失败:{str(e)}") return iccid def create_sim_table(): # 建表增加自增主键、时间戳字段,方便取最新记录、追溯变更时间 db_cursor.execute('''CREATE TABLE IF NOT EXISTS SimRecord( id INTEGER PRIMARY KEY AUTOINCREMENT, iccid VARCHAR NOT NULL, record_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP )''') conn.commit() def get_lastest_iccid(): """查询数据库中存储的最新一条ICCID记录""" db_cursor.execute('SELECT iccid FROM SimRecord ORDER BY id DESC LIMIT 1') result = db_cursor.fetchone() return result[0] if result else None def sim_data_entry(): new_iccid = str(get_sim_number()) old_iccid = get_lastest_iccid() # 变更判断逻辑 iccid_changed = False if old_iccid is None: print("无历史记录,首次写入ICCID") elif new_iccid != old_iccid: iccid_changed = True print(f"ICCID发生变更,旧值:{old_iccid},新值:{new_iccid}") else: print("ICCID与历史记录一致,无变更") # 插入新记录,保留全量历史轨迹,不需要的话可以改成仅变更时插入,或者单条记录覆盖更新 db_cursor.execute('INSERT INTO SimRecord(iccid) VALUES (?)', (new_iccid,)) conn.commit() # 返回变更标记、新旧值,方便后续业务逻辑使用 return iccid_changed, new_iccid, old_iccid # 业务调用 if __name__ == "__main__": create_sim_table() change_status, current_val, last_val = sim_data_entry() db_cursor.close() conn.close()
可选调整说明
- 如果你一定要把变更判断的变量放到
get_sim_number()函数内部,只需要把get_lastest_iccid()的查询逻辑移到该函数里即可,但非常不推荐这种写法,硬件读写逻辑和数据库存储逻辑强耦合,后续修改存储方式或者串口逻辑都要改动核心读取函数,维护成本很高 - 如果不需要保留所有历史ICCID记录,只需要存最新的一条值,可以把表的自增主键去掉,每次写入前先清空表,或者固定更新id=1的记录即可,不需要每次都插入新行
- 读取串口的逻辑可以根据你实际的模块返回格式调整解析规则,避免出现解析出空值、特殊字符导致误判变更的情况
内容的提问来源于stack exchange,提问作者Alec
相关产品推荐
相关产品推荐

