플라스크 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"
가 없으면 작동하지 않기 때문에 enctype="multipart/form-data"
를 사용해야 합니다.
이제 가장 먼저 해야 할 일은 파일에 대한 정보와 파일 데이터를 보유할 모델을 만드는 것입니다. 우리는 SQLAlchemy 모델이 될 이 클래스를 File_Uploader
라고 부를 것입니다.
이 모델에는 몇 가지 필드가 필요하므로 기본 키가 될 ID를 만든 다음 사용자가 양식을 통해 파일을 업로드할 때 파일 이름이 될 File_Name
을 추가합니다. 마지막은 데이터베이스 내부에 저장된 파일의 원시 데이터인 DATA
입니다.
이 특정 데이터의 경우 데이터베이스에 임의의 이진 데이터를 저장할 수 있는 LargeBinary
라는 데이터 유형을 사용해야 합니다. 일반적으로 데이터베이스에 파일을 저장하지 않지만 메타데이터는 데이터베이스에 저장합니다.
파일이 많지 않거나 제한으로 인해 모든 것을 데이터베이스에 보관하려는 경우 파일을 데이터베이스에 저장할 수 있습니다. 파일 데이터를 단일 테이블의 다른 열과 결합하면 성능 문제가 발생할 수 있습니다.
파일 데이터가 포함된 이 테이블이 커지면 성능 문제가 발생할 수 있지만 원하는 경우 할 수 있습니다. 그것이 우리가 이것을 만드는 이유입니다.
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 Viewer로 드래그하면 테이블이 생성된 것을 확인할 수 있습니다.
이제 이 앱을 실행하고 파일을 업로드 하겠습니다. 그러면 양식에서 파일을 업로드할 수 있습니다.
서버를 실행한 후 파일을 제출하기 위해 양식에 액세스할 경로를 지정합니다. 이러한 명령을 사용하여 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