Python:就地更新CSV文件



是否有一种明智的方法来更新CSV数据,在同一文件中,一次一行?

我有一个CSV的记录要检查并可能修复,这是我用临时脚本解决的一次性任务。该脚本将需要迭代才能使其正确工作。它将对每个记录进行分类,决定一个操作,尝试该操作并记录结果。我想将这些阶段附加到CSV:

id,status,action,result
123
234
345
456

id,status,action,result
123,OK,None
234,INVALID,Fix,OK
345,INVALID,Fix
456

哦,不,我的脚本崩溃,而试图修复345由于一个bug!因此,我将修复该错误并再次运行脚本,它将跳过status:OKresult:OK:

的行。
id,status,action,result
123,OK,None
234,INVALID,Fix,OK
345,INVALID,Fix,OK
456,OK,None

这可能吗?

一种方法是将CSV加载到内存中,然后覆盖原始文件:

fieldnames = "id status action result".split()
data = []
def process_and_update(record):
if record["status"] != "OK":
...

with open("file.csv", "r", newline="") as input_file:
reader = csv.DictReader(input_file, fieldnames=fieldnames)
next(reader) # skip header row
for r in reader:
data.append(r)
with open("file.csv", "w", newline="") as output_file:
writer = csv.DictWriter(output_file, fieldnames=fieldnames)
writer.writeheader()
for record in data:
process_and_update(record)
writer.writerow(record)

这不起作用,因为如果process_and_update(record)抛出意外错误,那么剩余的数据将丢失。

我目前使用的方法是写入一个单独的文件:

with open("file1.csv", "r", newline="") as input_file, 
open("file2.csv", "w", newline="") as output_file:

reader = csv.DictReader(input_file, fieldnames=fieldnames)
next(reader)
writer = csv.DictWriter(output_file, fieldnames=fieldnames)
writer.writeheader()
for record in reader:
record.update(process_and_update(record))
writer.writerow(record)

但是这需要每次为脚本提供正确的文件名。如果我继续使用原始文件作为输入,它将一遍又一遍地进行状态检查,这是缓慢的。

或者我应该将数据放入sqlite文件中?

找到了另一个部分答案,但如果存在未处理的错误,则会损坏文件:

with open(filename, "r", newline="") as input_file, 
open(filename, "r+", newline="") as output_file:
reader = csv.DictReader(input_file)
writer = csv.DictWriter(output_file, fieldnames=reader.fieldnames)
writer.writeheader()
for record in reader:
print(f"{record['id']}... ", end="")

if record["id"] == "345":
print("Fail")
raise Exception("simulated crash")

else:
print("OK")
record["result"] = "OK"

writer.writerow(record)

with output_file上下文结束时,将DictWriter写入文件。如果由于未处理的异常而结束,则部分覆盖原始文件:

id,status,action,result
123,
234,
345,
456,
567,
678,
789,
890,

id,status,action,result
123,,,OK
234,,,OK
6,        <--- "345,n456," overwritten
567,
678,
789,
890,

所以,如果你确信你永远不会崩溃,这个解决方案是有效的。否则,最好使用单独的输入文件和输出文件。

相关内容

  • 没有找到相关文章

最新更新