Flask文件上传重命名压缩功能失效求助(附代码片段)
我来帮你搞定重命名和压缩失效的问题,同时把你需要的全流程功能(上传→重命名→压缩→保存→解压→删Zip→存数据库)都补全。先看修复后的完整代码,再给你拆解关键修复点:
修复后的完整代码
import os import zipfile from flask import Flask, request import random import string # 假设用SQLAlchemy操作数据库,你可以替换成自己的数据库连接方式 from sqlalchemy import create_engine, Column, String, Integer from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker app = Flask(__name__) # 数据库配置(根据你的实际情况修改) DB_URI = 'mysql+pymysql://user:password@localhost/db_name' engine = create_engine(DB_URI) Base = declarative_base() Session = sessionmaker(bind=engine) session = Session() # 数据库模型:存储文件名和大小 class UploadedFile(Base): __tablename__ = 'uploaded_files' id = Column(Integer, primary_key=True) filename = Column(String(255), nullable=False) file_size = Column(Integer, nullable=False) # 确保表存在(首次运行时执行) Base.metadata.create_all(engine) # 生成随机字符串的函数 def generate_random(length): return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length)) @app.route('/temp/upload', methods=['POST']) def upload(): if request.method == 'POST': try: f = request.files['file'] if not f: return "No file uploaded", 400 # 1. 生成新文件名(保留原后缀) random_str = generate_random(5) original_name, ext = os.path.splitext(f.filename) new_filename = f"{random_str}{ext}" print(f"New filename: {new_filename}") # 2. 指定保存路径(确保目录存在) save_dir = './uploaded_files' zip_dir = './zip_files' extract_dir = './extracted_files' os.makedirs(save_dir, exist_ok=True) os.makedirs(zip_dir, exist_ok=True) os.makedirs(extract_dir, exist_ok=True) # 保存重命名后的文件 file_path = os.path.join(save_dir, new_filename) f.save(file_path) print(f"File saved to: {file_path}") # 3. 压缩为Zip文件 zip_filename = f"{random_str}.zip" zip_path = os.path.join(zip_dir, zip_filename) with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zip_ref: # 把文件添加到Zip,用新文件名作为归档内的名称 zip_ref.write(file_path, arcname=new_filename) print(f"Zip file created: {zip_path}") # 4. 解压Zip文件 with zipfile.ZipFile(zip_path, 'r') as zip_ref: zip_ref.extractall(extract_dir) print(f"Zip file extracted to: {extract_dir}") # 5. 删除Zip文件 os.remove(zip_path) print(f"Zip file deleted: {zip_path}") # 6. 获取文件大小并存入数据库 file_size = os.path.getsize(file_path) new_file_record = UploadedFile(filename=new_filename, file_size=file_size) session.add(new_file_record) session.commit() print(f"File info saved to database: {new_filename}, {file_size} bytes") return "Upload and processing completed successfully", 200 except Exception as e: # 回滚数据库操作如果发生异常 session.rollback() print(f"Error occurred: {str(e)}") return f"Processing failed: {str(e)}", 500 if __name__ == '__main__': app.run(debug=True)
关键修复&注意点
- 重命名文件的正确姿势:
你之前的代码可能没保留原文件后缀,或者拼接方式错误。这里用os.path.splitext拆分原文件名和后缀,再和随机字符串拼接,确保文件格式不会丢失。 - 压缩Zip的核心修复:
- 必须用
zipfile.ZIP_DEFLATED启用压缩(默认是不压缩的存储模式); - 压缩前要确保文件已经成功保存到本地路径,否则会找不到文件;
- 用
arcname参数指定Zip归档内的文件名,避免把完整路径打包进去。
- 必须用
- 路径处理的坑:
一定要用os.path.join拼接路径,避免跨平台的路径分隔符问题;同时用os.makedirs(..., exist_ok=True)确保目标目录存在,否则会抛出路径不存在的错误。 - 异常处理与数据库回滚:
加入了全局异常捕获,一旦流程中出现错误(比如压缩失败、数据库插入失败),会回滚数据库操作,避免脏数据。 - 文件大小获取:
用os.path.getsize获取文件的字节大小,确保存入数据库的数值准确。
内容的提问来源于stack exchange,提问作者Sri




