在Python中为非DB代码编写事务
python的一段代码正在编写/创建多个文件。 我想把它放在一个事务的方式,所以一切都是回滚,如果其中一个文件的创建失败。这将有助于节省硬盘空间,并避免失败事务中的无用文件 具体地说,通过向我的python服务器发送图片:在Python中为非DB代码编写事务,python,file,transactions,rollback,Python,File,Transactions,Rollback,python的一段代码正在编写/创建多个文件。 我想把它放在一个事务的方式,所以一切都是回滚,如果其中一个文件的创建失败。这将有助于节省硬盘空间,并避免失败事务中的无用文件 具体地说,通过向我的python服务器发送图片: 它首先保存原始文件full res 创建pic的较小版本 保存这个较小的verion 交易成功 然而,由于某些原因,步骤2或3可能会失败。如何回滚步骤1 解决方案应该是通用的,因为可能有更多的步骤 Python中有常见的事务技巧吗?我的解决方案 它在系统的默认临时目录(/tm
/tmp
在linux上)中创建一个临时目录,并返回一个pathlib.Path
对象,您可以在其中写入文件,如果一切都成功,它将最终将内容移动到目标,如果不是什么都不会发生
无论哪种方式,它都会在完成后进行清理,并删除写入临时目录的数据
导入临时文件
进口舒蒂尔
输入import ContextManager,Union
从pathlib导入路径
从contextlib导入contextmanager
@上下文管理器
def transactional_mkdir(目标:Union[str,Path],overwrite:bool=False)->ContextManager[Path]:
"""
创建一个目录并获取对它的引用,如果在所有写入过程中遇到任何未处理的故障,则在上下文中创建该目录并获取对它的引用
对目录所做的操作将被撤消
:param destination:要写入和创建的目标目录
:param overwrite:如果为True,将覆盖目标(如果存在)
:return:Path对象到目标目录
"""
#验证输入
目的地=路径(目的地)
如果未覆盖,则覆盖和目标.exists():
raise FileExistsError(f'目标已存在。若要覆盖,请使用“overwrite=True”')
#创建临时目录
temp_dir=Path(tempfile.mkdtemp())
尝试:
产量-温度-方向-给予控制
#删除现有的
如果destination.exists():
如果destination.is_dir():
shutil.rmtree(目标)#删除目录
其他:
destination.unlink()#删除文件
#保存到目的地
航天飞机移动(临时方向,目的地)
最后:
shutil.rmtree(临时目录)#删除目录
您可以使用try/except/finally模式来处理此类操作,您应该尝试一下,并用一些代码更新您的问题。这应该可以通过使用来实现。您知道步骤1本身不能回滚,但如果后续步骤失败,您始终可以删除该文件,对吗?是的,这就是我所说的回滚