Flasche send_file()

Salman Mehmood 15 Februar 2024
Flasche send_file()

Wir werden mit dieser Erklärung lernen, wie man Dateien in die SQLAlchemy-Datenbank hochlädt und diese Dateien dann aus der Datenbank in Flask herunterlädt.

Datei aus der SQLAlchemy-Datenbank in Flask hochladen und herunterladen

Wir haben eine einfache Flask-App mit SQLAlchemy, und wir werden die Vorlage verwenden, um eine Datei aus einer Datenbank hoch- und herunterzuladen. Die Funktion send_file() ermöglicht es uns, eine Datei anstelle von HTML zurückzugeben.

from flask import Flask, request, send_file, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///db.sqlite3"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)


@app.route("/", methods=["GET", "POST"])
def Main_page():
    return render_template("index.html")

Wir haben ein einfaches Formular in der Datei index.html erstellt. Wir müssen enctype="multipart/form-data" verwenden, wenn wir mit Formularen arbeiten, die Dateien hochladen, denn wenn wir das nicht haben, wird es nicht funktionieren.

Als erstes müssen wir nun ein Modell erstellen, das einige Informationen über die Datei und Daten für die Datei enthält. Wir nennen diese Klasse File_Uploader, die ein SQLAlchemy-Modell sein wird.

Dieses Modell benötigt einige Felder, also erstellen wir eine ID, die der Primärschlüssel sein wird, und als nächstes fügen wir einen File_Name hinzu, der der Dateiname ist, wenn der Benutzer die Datei über das Formular hochlädt. Der letzte ist DATA, die Rohdaten der Datei, die in der Datenbank gespeichert sind.

Für diese speziellen Daten müssen wir einen Datentyp namens LargeBinary verwenden, der es uns erlaubt, beliebige Binärdaten in der Datenbank zu speichern. Denken Sie daran, dass wir normalerweise keine Dateien in der Datenbank speichern, aber wir speichern die Metadaten in der Datenbank.

Wir könnten die Dateien in der Datenbank speichern, wenn wir nicht viele Dateien haben oder aufgrund von Einschränkungen alles in der Datenbank behalten möchten. Es kann zu Leistungsproblemen kommen, wenn Sie die Dateidaten mit anderen Spalten in einer einzelnen Tabelle kombinieren.

Es kann zu Leistungsproblemen kommen, wenn diese Tabelle mit den Dateidaten groß wird, aber Sie können, wenn Sie möchten. Deshalb schaffen wir das.

class File_Uploader(db.Model):
    File_ID = db.Column(db.Integer, primary_key=True)
    File_Name = db.Column(db.String(50))
    DATA = db.Column(db.LargeBinary)

Wir wollen die Datei aus dem Formular nehmen und sicherstellen, dass sie funktioniert. Innerhalb der Funktion Main_page() setzen wir die if-Anweisung, um Post-Requests zu verarbeiten.

Jetzt erhalten wir Dateien mit request.files['file'], speichern sie in der Variablen und nennen sie Got_File. Dadurch werden alle in der Anfrage gesendeten Dateien mit dem bestimmten Schlüssel abgerufen, den wir aus dem Formular senden.

if request.method == "POST":
    Got_File = request.files["file"]

Im nächsten Schritt laden wir diese in die Datenbank hoch, die das Modell File_Uploader verwendet. Wir übergeben Got_File.filename an das Feld File_Name und dann die Daten der Datei an das Feld DATA.

Got_File.read() nimmt alle Binärdaten für die Datei und weist sie dann dem Ort zu, an dem wir sie ablegen. Dann fügen wir eine Sitzung hinzu und übertragen die Daten.

file_upload = File_Uploader(File_Name=Got_File.filename, DATA=Got_File.read())
db.session.add(file_upload)
db.session.commit()
return f"Uploaded: {Got_File.filename}"

Jetzt müssen wir eine Datenbank und eine Tabelle innerhalb der Datenbank erstellen, also öffnen wir eine Python-Shell im selben Verzeichnis, in dem sich unsere Datei app.py befindet, und verwenden die folgenden Befehle:

from app import db

db.create_all()

Wenn wir uns das Stammverzeichnis ansehen, sehen wir eine Datenbankdatei namens db. Wenn wir diese Datei in den SQLite Viewer ziehen, können wir sehen, dass die Tabelle erstellt wurde.

Flask send_file() Ausgabe 1

Jetzt führen wir diese App aus und laden eine Datei hoch. Dann können wir die Dateien aus dem Formular hochladen.

Nachdem wir den Server ausgeführt haben, treffen wir die Route, von der aus wir auf das Formular zugreifen, um die Datei zu übermitteln. Wir verwenden diese Befehle, um die Flask-App einzurichten und diese App auszuführen.

set FLASK_APP='app.py'
flask run

Nach dem Hochladen von Dateien können wir sehen, dass die Dateien erfolgreich hochgeladen wurden, und wenn wir uns die Tabelle ansehen, haben wir die ID und den Dateinamen.

Flask send_file() Ausgabe 2

Wir können jeden Dateityp hochladen; es kann eine mp3-Datei, eine Filmdatei oder eine Codedatei sein, was auch immer es ist.

Jetzt erstellen wir eine Route zum Herunterladen der Datei, die wir in die Datenbank hochgeladen haben, und wir werden in dieser Route eine Variable namens File_ID haben. Jetzt führen wir die Abfrage in der Datenbank mit dieser ID durch und holen Daten aus der Datenbank für diese bestimmte Zeile.

@app.route('/download/<File_ID>')

Wir müssen die Klasse BytesIO aus dem Modul io importieren. Auf diese Weise können wir die Binärdaten in die Datenbank übernehmen und sie dann in ein Format konvertieren, mit dem Flask die Datei neu generieren kann.

Wir senden die Datei mit der Funktion send_file() zurück. Dann übergeben wir innerhalb der Klasse BytesIO die Daten mit der entsprechenden Spalte.

Dann übergeben wir das Schlüsselwortargument attachment_filename, weil wir einen Anhang verwenden werden.

def download(File_ID):
    Got_File = File_Uploader.query.filter_by(File_ID=File_ID).first()
    return send_file(
        BytesIO(Got_File.DATA),
        attachment_filename=Got_File.File_Name,
        as_attachment=True,
    )

Werfen wir einen Blick darauf. Wir gehen zur Download-Seite und übergeben die ID; Wenn wir diese Route erreichen, können wir die Datei herunterladen.

Flask send_file() Ausgabe 3

Vollständiger Python-Code:

from flask import Flask, request, send_file, render_template
from flask_sqlalchemy import SQLAlchemy
from io import BytesIO

app = Flask(__name__)

app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///db.sqlite3"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)


class File_Uploader(db.Model):
    File_ID = db.Column(db.Integer, primary_key=True)
    File_Name = db.Column(db.String(50))
    DATA = db.Column(db.LargeBinary)


@app.route("/", methods=["GET", "POST"])
def Main_page():
    if request.method == "POST":
        Got_File = request.files["file"]

        file_upload = File_Uploader(File_Name=Got_File.filename, DATA=Got_File.read())
        db.session.add(file_upload)
        db.session.commit()

        return f"Uploaded: {Got_File.filename}"
    return render_template("index.html")


@app.route("/download/<File_ID>")
def download(File_ID):
    Got_File = File_Uploader.query.filter_by(File_ID=File_ID).first()
    return send_file(
        BytesIO(Got_File.DATA),
        attachment_filename=Got_File.File_Name,
        as_attachment=True,
    )

Die HTML-Datei, die wir in der Flask-App verwendet haben:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Uploader </title>
    <style>
        body {
          margin: 0;
        }

        .center {
          display: flex;
          justify-content: center;
          align-items: center;
          height: 100vh;
        }
      </style>
</head>
<body>
    <div class="center">
        <form method="POST" action="/" enctype="multipart/form-data">
            <input type="file" name="file">
            <button>Submit</button>
        </form>
    </div>
</body>
</html>
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

Verwandter Artikel - Flask File