フラスコ send_file()
この説明では、ファイルを SQLAlchemy データベースにアップロードし、それらのファイルを Flask のデータベースからダウンロードする方法を学びます。
Flask で SQLAlchemy データベースからファイルをアップロードおよびダウンロードする
SQLAlchemy を使用した基本的な Flask アプリがあり、テンプレートを使用してデータベースからファイルをアップロードおよびダウンロードします。 send_file()
関数を使用すると、HTML の代わりにファイルを返すことができます。
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")
index.html
ファイル内に単純なフォームを作成しました。 ファイルをアップロードするフォームで作業する場合は、enctype="multipart/form-data"
を使用する必要があります。これがないと機能しません。
ここで、最初に行う必要があるのは、ファイルに関する情報とファイルのデータを保持するモデルを作成することです。 このクラスを File_Uploader
と呼びます。これは SQLAlchemy モデルになります。
このモデルにはいくつかのフィールドが必要になるため、主キーとなる ID を作成し、次に、ユーザーがフォームからファイルをアップロードするときのファイル名となる File_Name
を追加します。 最後は DATA
で、データベース内に保存されているファイルの生データです。
この特定のデータには、LargeBinary
と呼ばれるデータ型を使用する必要があります。これにより、任意のバイナリ データをデータベースに格納できます。 通常、ファイルはデータベースに保存されませんが、メタデータはデータベースに保存されることに注意してください。
多くのファイルがない場合、または制限のためにすべてをデータベースに保持したい場合は、データベースにファイルを格納できます。 ファイル データを 1つのテーブル内の他の列と組み合わせると、パフォーマンスの問題が発生する可能性があります。
ファイルデータを含むこのテーブルが大きくなると、パフォーマンスの問題が発生する可能性がありますが、必要に応じて実行できます。 それが私たちがこれを作成している理由です。
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)
フォームからファイルを取得し、それが機能することを確認します。 Main_page()
関数内で、投稿リクエストを処理する if
ステートメントを設定します。
ここで、request.files['file']
を使用してファイルを取得し、それらを変数に格納して、Got_File
という名前を付けます。 これにより、フォームから送信された特定のキーを使用して、リクエストで送信されたすべてのファイルが取得されます。
if request.method == "POST":
Got_File = request.files["file"]
次のステップでは、これをデータベースにアップロードします。これは、File_Uploader
というモデルを使用します。 Got_File.filename
を File_Name
フィールドに渡し、次にファイルのデータを DATA
フィールドに渡します。
Got_File.read()
は、ファイルのすべてのバイナリ データを取得し、それをどこにでも割り当てます。 次に、セッションを追加してデータをコミットします。
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}"
次に、データベースとデータベース内にテーブルを作成する必要があるため、app.py
ファイルが配置されているディレクトリと同じディレクトリで Python シェルを開き、次のコマンドを使用します。
from app import db
db.create_all()
ルート ディレクトリを見ると、db
というデータベース ファイルがあります。 このファイルを SQLite ビューアー内にドラッグすると、テーブルが作成されていることがわかります。
次に、このアプリを実行してファイルをアップロードします。 次に、フォームからファイルをアップロードできるようになります。
サーバーを実行した後、フォームにアクセスしてファイルを送信するルートにアクセスします。 これらのコマンドを使用して、Flask アプリをセットアップし、このアプリを実行します。
set FLASK_APP='app.py'
flask run
ファイルをアップロードした後、ファイルが正常にアップロードされたことを確認できます。テーブルを見ると、ID とファイル名が表示されます。
あらゆる種類のファイルをアップロードできます。 mp3、ムービー ファイル、コード ファイルなど、どのようなものでもかまいません。
ここで、データベースにアップロードしたファイルをダウンロードするルートを作成します。このルートには、File_ID
という変数があります。 次に、その ID を使用してデータベースでクエリを実行し、その特定の行のデータをデータベースから取得します。
@app.route('/download/<File_ID>')
io
モジュールから BytesIO
クラスをインポートする必要があります。 これにより、データベース内のバイナリ データを取得し、Flask がファイルの再生成に使用できる形式に変換できます。
send_file()
関数を使用してファイルを返します。 次に、BytesIO
クラス内で、対応する列でデータを渡します。
次に、添付ファイルを使用するため、attachment_filename
キーワード引数を渡します。
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,
)
これを見てみましょう。 ダウンロード ページに移動し、ID を渡します。 このルートに到達すると、ファイルをダウンロードできます。
完全な Python コード:
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,
)
Flask アプリ内で使用した HTML ファイル:
<!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>
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