【发布时间】:2020-04-23 18:02:48
【问题描述】:
我在烧瓶应用程序中 os.makedir 的行为非常奇怪。
我有一个用于上传图片的 API 端点。每个图像应根据条件分组到目录中。如果目录不存在,则应创建目录。
最初,我的应用中有这段代码:
# create needed dir if doesn't exist
if not os.path.isdir(os.path.dirname(abs_path)):
os.mkdir(os.path.dirname(abs_path))
# create a file and save it into a needed place
with open(abs_path, 'wb') as f:
shutil.copyfileobj(fp, f)
f.flush()
在 90% 的情况下,它的效果都很好。但是当请求中有两个文件时,应该放在同一个目录中,并且该目录尚未创建,我得到了这个:
flask_1 | File "/app/storage.py", line 101, in save_file
flask_1 | os.mkdir(os.path.dirname(abs_path))
flask_1 | FileExistsError: [Errno 17] File exists: '/static/df273d04909e71beb8b63b4d1b1c0a969ee6fc15'
它可以在 1 线程的烧瓶调试模式下以 100% 的成功率在本地复制。似乎是某种 Linux/docker 或某种缓存竞争条件。
然后我将代码简单地更改为这个:
if not os.path.isdir(os.path.dirname(abs_path)):
try:
os.mkdir(os.path.dirname(abs_path))
except FileExistsError:
# Another thread was already created the directory when
# several simultaneous requests has come
if os.path.isdir(os.path.dirname(abs_path)):
pass
else:
raise
# create a file and save it into a needed place
with open(abs_path, 'wb') as f:
shutil.copyfileobj(fp, f)
f.flush()
问题就解决了。
但我担心在生产中使用此代码,因为同样的检查产生不同的结果是很奇怪的。
在继续第一次请求处理之前,如何确保目录确实创建了?
附:文件已就位,第二个代码 sn-p 两个文件均已就位。第一个只有目录中的第一个文件,第二个错误。
I.E.使用第一个代码 sn -p Flask 认为一切正常并继续
【问题讨论】:
-
你确定进程是单线程运行的?
标签: python python-3.x flask operating-system race-condition