#python #sql #flask #sqlalchemy #blob
Вопрос:
Я пытаюсь загрузить книги в sqlite3 в виде pdf. Я написал этот код, который загружает :
- Автор
- Название
- pdf-файл истории, но часть больших двоичных объектов, похоже, здесь не работает:
class Book(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) author = db.Column(db.String(50), unique=False) title = db.Column(db.String(50), unique=False) pdf= db.Column(db.Blob(10000000)) @app.route('/uploadStory', methods=['GET', 'POST']) def uploadStory(): new_book = Book(author=form.author.data, title=form.title.data, pdf=form.pdf.data) db.session.add(new_book) db.session.commit()
Как я могу гарантировать, что пользователь сможет загрузить книгу в формате PDF? Идеально
- Я хочу, чтобы пользователи загружали целые истории
- Я хочу, чтобы размер большого двоичного объекта был очень большим
- Я не хочу хранить истории локально, а затем использовать путь
- Я хочу хранить их с помощью большого двоичного объекта
Ответ №1:
Я не знаю, как это сделать с помощью SQLAlchemy, но вот способ vanilla Python/Колба:
from flask import Flask, render_template, request, redirect, url_for import sqlite3 app = Flask(__name__) def insert_user_data(author, title, pdf): con = sqlite3.connect("user_data.sqlite") cur = con.cursor() query = """ INSERT INTO user_data (author, title, pdf) VALUES (?, ?, ?); """ cur.execute(query, [author, title, pdf]) con.commit() @app.route("/", methods=["GET", "POST"]) def home(): if request.method == "POST": pdf = request.files["pdf"].read() author = request.form["author"] title = request.form["title"] insert_user_data(author, title, pdf) return redirect(url_for("home")) return render_template("index.html")
Это предполагает такую схему БД:
CREATE TABLE user_data ( id INTEGER PRIMARY KEY AUTOINCREMENT, author TEXT, title TEXT, pdf BLOB );
И простой index.html
:
lt;!DOCTYPE htmlgt; lt;html lang="en"gt; lt;headgt; lt;meta charset="UTF-8"gt; lt;meta http-equiv="X-UA-Compatible" content="IE=edge"gt; lt;meta name="viewport" content="width=device-width, initial-scale=1.0"gt; lt;titlegt;Save PDFlt;/titlegt; lt;stylegt; input { display: block; } lt;/stylegt; lt;/headgt; lt;bodygt; lt;form method="POST" action="{{ url_for('home') }}" enctype="multipart/form-data"gt; lt;input type="text" name="author" placeholder="author" /gt; lt;input type="text" name="title" placeholder="title" /gt; lt;input type="file" name="pdf" /gt; lt;button type="submit"gt;Submitlt;/buttongt; lt;/formgt; lt;/bodygt; lt;/htmlgt;
Когда я запускаю это, а затем запускаю другой скрипт, чтобы извлечь pdf
его из базы данных и записать в файл (чтобы посмотреть, сработало ли это), все выглядит хорошо:
import sqlite3 con = sqlite3.connect("user_data.sqlite") cur = con.cursor() query = """ SELECT pdf FROM user_data WHERE id = 1; """ result = cur.execute(query).fetchone()[0] with open("think-python.pdf", mode="wb") as file: file.write(result)
Вот результирующая структура файла:
➜ blob-pdf ls app.py main.py __pycache__ schema.sql templates think-python.pdf user user_data.sqlite ➜ blob-pdf file think-python.pdf think-python.pdf: PDF document, version 1.5
А вот файл после извлечения из БД: