【问题标题】:Storing and retrieving a PDF from Python's Mongoengine从 Python 的 Mongoengine 存储和检索 PDF
【发布时间】:2022-01-04 22:38:45
【问题描述】:

我最近了解到,每当我更新网站时,我上传到 Heroku 网站的 PDF 文件和图像都会被删除。因此,我一直在尝试使用 Mongoengine(使用 Flask 和 Python)将我的 PDF 存储在我的 MongoDB 数据库中,然后检索它们并将它们存储在静态文件夹中(我能够用我的图像成功地做到这一点),不走运。

下面是我的 Mongoengine 类的相关代码:

class Article(Document):
    uploaded_content = FileField() # Field for storing PDF
    uploaded_content_name = StringField() # File name for PDF

我尝试存储 PDF 的 Flask 路由的相关代码:

data = Article()
if request.files['uploaded-article']:
    data.uploaded_content = request.files['uploaded-article']
    # uploaded_content_name given random name below, and stored in
    # database

然后这是我的代码,它试图从 mongoengine 检索 PDF,并将其保存到我的博客文件夹:

articles = Article.objects()
for art in articles:
    path = os.path.join(app.config['BLOG_FOLDER'], art.uploaded_content_name)
    if not os.path.isfile(path):
        f = open(art.uploaded_content.read(), 'wb') # This lines gives the error
        f.save(os.path.join(app.config['BLOG_FOLDER'] + art.uploaded_content_name), "PDF")
    

当我尝试打开存储在数据库中的 PDF 文件时,出现错误的那一行。我尝试了许多不同的方法并得到了各种错误,但我得到的一个是: No such file or directory: b''。我可以确认,如果我 read() 数据库对象,它只是一个空字节字符串。

我还尝试通过存储来自 Flask 请求对象的打开的 PDF 将我的烧瓶路由更改为下面的代码。但是,当我尝试打开它时,这给了我错误ValueError: embedded null byte。然而,read() 方法至少给了我一个很长的字节串。

data = Article()
if request.files['uploaded-article']:
    # store the PDF in the blog folder
    article_pdf = request.files['uploaded-article']
    article_pdf.save(os.path.join(app.config['BLOG_FOLDER'], article_pdf_filename))
    # Open the PDF just stored in the blog folder
    with open(os.path.join(app.config['BLOG_FOLDER'], article_pdf_filename), 'rb') as f:
        # Store the opened PDF in the database
        data.uploaded_content.put(f)
        f.close()
    # uploaded_content_name given random name below, and stored in
    # database

我尝试的另一件随机事情是尝试使用 BytesIO 数据结构打开 PDF 文件,但它导致了与上述嵌入空字节相同的错误。

对于如何从我的 mongoengine 数据库中正确存储和检索我的 PDF 有什么建议吗?对于我的问题的复杂性,我深表歉意 - 但是,如果需要,我可以添加更多细节。如果有任何替代方法来存储我的 PDF,以免它们在 Heroku 上丢失,我也会将其视为有效的解决方案。

【问题讨论】:

  • 感谢您的建议,我会尽量远离 IO。您知道我可以使用哪种特定语法将它们存储为常规文件对象吗?我觉得我在使用 mongoengine 的 GridFS documentation 时步入正轨,但我更纠结于如何存储和检索这些 PDF。

标签: python flask pdf storage mongoengine


【解决方案1】:

作为未来的参考,这似乎不起作用,因为我在放入 pdf 时没有正确设置内容类型。我将 PDF 保存到 data.uploaded_content 字段时的原始代码是:

data.uploaded_content.put(f)

但是,我需要正确定义 mimetype:

data.uploaded_content.put(f, content_type='application/pdf')

通过此更改,它可以正常工作,并且我能够成功地将 PDF 存储在 mongoengine 中。至于成功上传后将PDF存储到文件夹中,我使用了以下代码:

if art.uploaded_content_name:
    extension = art.uploaded_content_name.rsplit('.', 1)[1].lower()
    path = os.path.join(app.config['BLOG_FOLDER'], art.uploaded_content_name)
    if not os.path.isfile(path):
        pdf = art.uploaded_content.read()
        with open(os.path.join(app.config['BLOG_FOLDER'], art.uploaded_content_name), 'wb') as f:
            f.write(pdf)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 2013-11-01
    • 2023-04-08
    相关资源
    最近更新 更多