Heroku临时文件系统中Python无法创建并读取文件的技术求助
嘿,我之前在Heroku上折腾文件读写的时候也踩过类似的坑,结合你的情况给你梳理几个可能的原因和解决办法:
先排查:是不是路径或权限的问题?
Heroku的临时文件系统虽然重启会清空,但在当前dyno运行期间是完全支持读写的,所以你说的“指定文件夹已存在但没创建文件”大概率不是临时文件系统的持久化问题,而是路径或权限没搞对:
确认文件路径是否正确
你用的是相对路径media/data_sets/test.csv,但Heroku上的工作目录可能和你本地不一样。建议在代码里加几行打印,确认实际的文件路径:import os print("当前工作目录:", os.getcwd()) print("文件绝对路径:", os.path.abspath(file_path))运行后去Heroku的日志里看输出,说不定文件被写到了你完全没预期的位置。
检查文件夹的读写权限
虽然Heroku的临时文件系统默认允许读写,但还是可以确认一下目标文件夹是否真的可写:folder_path = os.path.dirname(file_path) print("文件夹存在吗?", os.path.exists(folder_path)) print("文件夹可写吗?", os.access(folder_path, os.W_OK))如果输出显示文件夹不存在,那可能是你本地的空文件夹没被Git跟踪(Git不会提交空文件夹),导致部署到Heroku后这个文件夹没创建出来——这种情况可以在空文件夹里放一个
.gitkeep文件,让Git把它提交上去。
如果需要持久化保存文件(重启dyno不丢失)
如果你的需求是保存文件后,哪怕dyno重启或者跨dyno都能读取,那Heroku的临时文件系统肯定满足不了,必须用外部存储服务。常见的选择有AWS S3、Google Cloud Storage,或者Heroku官方的附加组件(比如AWS S3、Cloudinary)。
举个用boto3上传文件到S3的简单例子:
import boto3 import os # 从Heroku配置变量里获取AWS密钥 s3 = boto3.client( 's3', aws_access_key_id=os.getenv('AWS_ACCESS_KEY_ID'), aws_secret_access_key=os.getenv('AWS_SECRET_ACCESS_KEY') ) # 先按你的逻辑写入本地临时文件(只是临时存储,后续会上传) with open(file_path, 'w') as file: file.write(csv_header + '\n') for i in range(self.rows): line = next(generator) line += '\n' if i != self.rows - 1 else '' file.write(line) # 上传到S3 with open(file_path, 'rb') as file: s3.upload_fileobj(file, '你的S3桶名称', 'data_sets/test.csv') # 后续需要读取的话,从S3下载到本地临时路径 s3.download_file('你的S3桶名称', 'data_sets/test.csv', file_path)
记得在Heroku的「Settings」→「Config Vars」里添加AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY这两个环境变量。
其他注意点
- 如果你是在不同dyno之间共享文件(比如web dyno写,worker dyno读),每个dyno有独立的临时文件系统,这种情况下必须用外部存储,本地文件是互相不可见的;
- Heroku的临时文件系统有512MB的空间限制,如果你的文件过大也会出问题,但你的情况是没创建文件,应该暂时不用考虑这个。
内容的提问来源于stack exchange,提问作者The_Fenrir

