pyodbc操作Azure SQL时第5参数找不到数据类型错误如何解决?
问题原因
- 核心错误是
source_hash参数类型不匹配:代码中row是pyodbc查询返回的Row对象(本质是类元组结构),你打印哈希的时候用了''.join(row)做了转字符串处理,但赋值给source_hash的时候直接用了原始row对象,传入execute参数时驱动无法识别该类型,导致SQL Server误将哈希值内容识别为数据类型名称,抛出报错。 - 附加问题:你对所有API返回值用了
json.dumps(),这会给字符串额外套上一层双引号,比如原本md5值是xxx,dumps后会变成"\"xxx\"",写入数据库会多带不必要的引号,也可能导致字段长度不匹配。
修复方案
修改后可正常运行的代码如下:
# Scanning files def fileScan(): select_sql = "SELECT source_hash FROM [Downloads]" crsr.execute(select_sql) rows = crsr.fetchall() # Read all rows for row in rows: # 直接将row转为字符串赋值给source_hash,避免后续类型不匹配 source_hash = ''.join(row) print(source_hash) response = vt.get_file_report(source_hash) time.sleep(15) # 去掉json.dumps,直接取原始值,数字类型转为int适配数据库整数字段 md5 = response['results']['md5'] sha1 = response['results']['sha1'] sha256 = response['results']['sha256'] detections = int(response['results']['positives']) query = ( "UPDATE Downloads SET md5=?, sha1=?, sha256=?, detections=? " "WHERE source_hash=?" ) crsr.execute(query, (md5, sha1, sha256, detections, source_hash)) crsr.commit()
可选优化建议
- 可将
crsr.commit()放到for循环结束后执行,批量提交减少数据库IO开销,出错可以统一回滚。 - 执行UPDATE前可以加判断,确认API请求正常返回结果再写入,避免请求失败时脚本报错中断。
- 排查类型问题时可临时打印所有传入execute的参数类型:
print(type(md5), type(sha1), type(sha256), type(detections), type(source_hash)),确认所有参数都是字符串/数字等基础类型。
内容的提问来源于stack exchange,提问作者Dushan Dissanayake
相关产品推荐
相关产品推荐

