Python logger日志导出CSV出现异常转义字符问题排查求助
CSV导出出现多余转义字符问题的原因及解决方案
问题原因
- 所有现象都是Python标准
csv模块的正常逻辑,和你的日志内容、SQLite存储逻辑没有关系:- 默认配置下csv模块使用
csv.QUOTE_MINIMAL规则,只会对包含分隔符(你用的逗号)、换行符、引号的字段自动加双引号包裹。你的坐标日志内容里包含, lng的逗号,正好和CSV分隔符一致,所以会被加双引号,其他不含逗号的日志就不会有引号,这和你最初观察到的现象完全吻合。 - 你设置
quoting=csv.QUOTE_NONE后,csv模块不会再用引号包裹冲突字段,转而在和分隔符冲突的字符前自动加你指定的escapechar转义,所以逗号前面就多了你设置的#符号。 - 你把
escapechar改成空格后,所有和分隔符冲突的逗号前都会加一个空格转义,就出现了你看到的双倍空格、逗号前多空格的现象。
- 默认配置下csv模块使用
- 补充:你当前的SQL插入逻辑存在隐患,用字符串格式化拼接SQL语句,如果日志内容里出现单引号会直接插入失败,甚至有SQL注入风险。
解决方案
方案1(推荐):恢复默认CSV配置
默认的csv.QUOTE_MINIMAL是符合CSV标准的通用配置,所有主流CSV解析工具都会自动识别字段外的双引号,读取时会自动去除,不会影响日志内容的正常使用,代码如下:
with open(db_dump_filename, "w", newline="") as csv_dump_file: cols = ["Timestamp", "Level", "Source", "Message"] db_exporter = csv.writer(csv_dump_file) db_exporter.writerow(cols) db_exporter.writerows(entries)
方案2:更换CSV分隔符
如果你确实不想在字段外添加双引号,可以把CSV分隔符换成日志内容里不会出现的字符,比如制表符\t,就不会出现转义问题:
with open(db_dump_filename, "w", newline="") as csv_dump_file: cols = ["Timestamp", "Level", "Source", "Message"] db_exporter = csv.writer(csv_dump_file, delimiter="\t", quoting=csv.QUOTE_NONE) db_exporter.writerow(cols) db_exporter.writerows(entries)
修复SQL插入隐患
将字符串格式化拼接SQL改为参数化查询,避免单引号导致的插入失败和注入风险:
# 替换emit方法中原来的SQL插入逻辑 conn.execute( "INSERT INTO logs(Timestamp, Level, Source, Message) VALUES (?, ?, ?, ?)", (record.tstamp, record.levelno, record.name, record.message) )
内容的提问来源于stack exchange,提问作者rbaleksandar
相关产品推荐
相关产品推荐

