You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask上传文件到服务器目录并存路径到数据库报错如何解决

问题原因

代码报错是多个基础写法错误叠加导致的:

  • 缩进不符合Python语法规则:模型类的__repr__方法没有缩进在类体内,路由函数create()里除了前两行POST判断的代码,剩下的文件保存、数据库操作代码全部缩进到了函数外部,脱离请求上下文访问request对象会直接报错。
  • 取值逻辑错误:文件上传控件的内容存储在request.files中,用request.form取文件字段只能拿到空值;且数据库需要存储的是文件最终落盘的完整路径,不是表单的空字段值。
  • 类名不匹配:定义的数据库模型类名为some_to_db,实例化写入数据时用的类名是Article,会直接触发NameError找不到对应类。
  • 缺少前置校验:没有判断用户是否上传文件、上传目录是否存在、文件名是否合法,空值写入设置了nullable=False的数据库字段会直接触发约束报错。
  • 裸except捕获所有异常会吞掉真实报错信息,调试阶段无法定位具体问题。
修复方案
  • 修正所有代码缩进,确保类方法、路由内的逻辑都在对应代码块的缩进层级里
  • 统一模型类名,实例化时和定义的类名保持一致
  • 废弃用request.form取文件字段的写法,文件全部从request.files获取,文件保存完成后拼接好完整存储路径,再写入数据库
  • 增加基础上传校验:判断文件是否存在、文件名非空,提前创建好上传目录避免保存时报错
  • 调试阶段不要用裸except,打印具体异常信息方便排查问题,数据库操作失败时记得回滚会话
修正后代码

后端Flask代码

import os
from datetime import datetime
from flask import Flask, request, redirect, render_template
from flask_sqlalchemy import SQLAlchemy
from werkzeug.utils import secure_filename

app = Flask(__name__)
# 替换为实际的数据库连接地址
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 替换为服务器上实际的文件存储目录绝对路径
app.config['UPLOAD_FOLDER'] = '/var/www/upload_files'
# 自动创建上传目录,已存在则不报错
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)

db = SQLAlchemy(app)

# 统一模型类名,前后保持一致即可
class Article(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    file = db.Column(db.String(300), nullable=False)
    file1 = db.Column(db.String(300), nullable=False)
    date = db.Column(db.DateTime, default=datetime.utcnow)

    # __repr__ 必须缩进在类内部
    def __repr__(self):
        return '<Article %r>' % self.id

@app.route("/create", methods=['POST', 'GET'])
def create():
    if request.method == "POST":
        # 校验两个文件字段都存在
        if 'file' not in request.files or 'file1' not in request.files:
            return "请选择所有需要上传的文件"
        f = request.files['file']
        g = request.files['file1']
        # 校验文件名非空,避免用户未选文件就提交
        if f.filename == '' or g.filename == '':
            return "请选择有效上传文件"
        
        # 安全处理文件名,拼接完整保存路径后存储文件
        f_save_path = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(f.filename))
        f.save(f_save_path)

        g_save_path = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(g.filename))
        g.save(g_save_path)

        # 把文件实际存储路径写入数据库
        article = Article(file=f_save_path, file1=g_save_path)

        try:
            db.session.add(article)
            db.session.commit()
            return redirect('/admin')
        except Exception as e:
            db.session.rollback()
            # 调试阶段返回具体错误信息,生产环境请替换为友好提示
            return f"写入数据库报错: {str(e)}"
    # GET请求直接返回上传表单页面
    return render_template('create.html', title="UPLOAD")

if __name__ == '__main__':
    with app.app_context():
        # 首次运行自动建表,表已存在可注释该行
        db.create_all()
    app.run(debug=True)

HTML表单代码(原表单逻辑无问题,仅给按钮补充type="submit"兼容不同浏览器)

<form class="form-contact" method="post" enctype="multipart/form-data">
  <p><label>Some file 1</label><input type="file" name="file"/></p>
  <p><label>Some file 2</label><input type="file" name="file1"/></p>
  <button class="pushable" type="submit">
    <span class="shadow"></span>
    <span class="edge"></span>
    <span class="front">
      Submit
    </span>
  </button>
</form>
额外注意事项
  • 生产环境请关闭debug模式,不要把内部报错信息暴露给普通用户
  • 如果允许上传同名文件,建议给文件名拼接UUID等随机前缀,避免新文件覆盖旧文件
  • 给上传目录配置正确的读写权限,确保Flask运行进程有权限写入文件

内容的提问来源于stack exchange,提问作者Guvanch Akmammedov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:12:18