Python向文件追加JSON数据时的任务调度执行覆盖数据问题
Python向文件追加JSON数据时的任务调度执行覆盖数据问题
这种手动跑脚本完全正常,一放到任务调度就出数据覆盖的情况,确实挺闹心的。结合你的代码和场景,我来梳理下最可能的原因,以及对应的解决办法:
核心问题推测
你的代码逻辑本身是没问题的:读取现有JSON列表、追加新数据、再写回文件。但任务调度时出现覆盖,大概率是脚本运行时没能成功读取到原文件的内容,导致data变成了空列表,追加新数据后写回就直接覆盖了原有文件。
为什么手动能读到,调度就读不到?主要有这几个可能:
- 运行用户权限不一致:你手动运行用的是当前登录用户,而任务调度可能用的是系统账户(比如Local System)或者其他用户,这个用户没有访问共享目录
\\path\to\file\的读取权限,或者读取时无法获取到文件内容。 - 文件路径解析异常:虽然你写的是UNC绝对路径,但部分任务调度环境对共享路径的解析可能存在问题,导致实际读取的是一个不存在的文件(自动新建了空文件),后续写入自然就覆盖了原本的文件。
- 文件读取异常未被处理:如果调度运行时,文件刚好出现临时读写冲突或格式异常,你的代码没有做错误处理,会默认用空列表继续执行,最终覆盖原文件。
针对性解决办法
1. 先排查任务调度的运行环境
- 打开任务计划程序,找到你的任务,查看常规选项卡下的“安全选项”,确认运行用户和你手动运行的是同一个账户,或者该账户有共享目录的读写权限(包括读取现有文件的权限)。
- 在脚本开头加几行调试代码,把运行时的关键信息输出到日志文件,方便排查:
运行任务后查看日志,就能快速定位是不是路径或权限的问题。import os log_path = r"\\path\to\file\debug_log.txt" with open(log_path, 'a') as f: f.write(f"当前运行用户: {os.getlogin()}\n") f.write(f"当前工作目录: {os.getcwd()}\n") f.write(f"目标文件是否存在: {os.path.exists(r'\\path\to\file\datafile.txt')}\n") f.write(f"目标文件大小: {os.path.getsize(r'\\path\to\file\datafile.txt') if os.path.exists(r'\\path\to\file\datafile.txt') else '不存在'}\n")
2. 给代码加上异常处理和兜底逻辑
修改你的代码,确保读取文件失败时不会直接用空列表覆盖原有数据,同时修复代码里的笔误(va3应该是var3):
def datafile(): import json import os file_path = r"\\path\to\file\datafile.txt" var1 = # 你的变量值 var2 = # 你的变量值 var3 = # 你的变量值 new_vars = [var1, var2, var3] # 修复笔误:va3 → var3 # 确保文件存在,不存在则初始化空列表 if not os.path.exists(file_path): with open(file_path, 'w') as init_file: json.dump([], init_file) try: # 读取现有数据,确保是列表格式 with open(file_path, 'r') as file: data = json.load(file) if not isinstance(data, list): raise ValueError("文件内容不是预期的列表格式") except (json.JSONDecodeError, ValueError) as e: # 读取失败时,先备份原文件再初始化 backup_path = file_path + ".bak" if os.path.exists(file_path): os.rename(file_path, backup_path) data = [] # 追加新数据并写入 data.append(new_vars) with open(file_path, 'w') as output: json.dump(data, output) datafile()
3. 增加文件锁避免并发冲突
如果你的任务调度间隔比较短,有可能出现前一次脚本还没运行完,下一次就启动了,导致文件读写冲突。可以用filelock库来加锁,确保同一时间只有一个进程操作文件:
首先安装库:pip install filelock
然后修改代码:
from filelock import FileLock def datafile(): import json import os file_path = r"\\path\to\file\datafile.txt" lock_path = file_path + ".lock" # 锁文件路径 var1 = # 你的变量值 var2 = # 你的变量值 var3 = # 你的变量值 new_vars = [var1, var2, var3] # 使用文件锁确保原子操作 with FileLock(lock_path): # 初始化文件(如果不存在) if not os.path.exists(file_path): with open(file_path, 'w') as init_file: json.dump([], init_file) # 读取并验证数据 try: with open(file_path, 'r') as file: data = json.load(file) if not isinstance(data, list): data = [] except json.JSONDecodeError: data = [] # 追加写入 data.append(new_vars) with open(file_path, 'w') as output: json.dump(data, output) datafile()
总结
最可能的根源是任务调度的用户权限或路径解析问题,导致脚本读取不到原文件内容。先通过日志排查环境问题,再给代码加上异常处理和锁机制,应该就能解决数据被覆盖的问题了。
备注:内容来源于stack exchange,提问作者tonydanza123
相关产品推荐
相关产品推荐

