如何通过PyMongo和Bottle从MongoDB数据库显示图像?

时间:2014-01-13 08:54:58

标签: mongodb python-2.7 pymongo bottle gridfs

所需行为

将图像上传到GridFS,然后在浏览器中显示(只是为了了解GridFS的工作原理)。

当前行为

图像上传到GridFS集合(我可以通过shell访问它),然后返回500错误。

错误

Error: 500 Internal Server Error

Sorry, the requested URL 'https:/mysite.com/form_action_path' caused an error:

表格

<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="data" />
<input type="submit" value="submit">
</form>

# relevant libraries
import gridfs
from bottle import response

@route('/upload', method='POST')
def do_upload():
    data = request.files.data
    name, ext = os.path.splitext(data.filename)
    if ext not in ('.png','.jpg','.jpeg'):
        return "File extension not allowed."
    if data and data.file:
        raw = data.file.read()
        filename = data.filename
        dbname = 'grid_files'
        db = connection[dbname]
        fs = gridfs.GridFS(db)
        fs.put(raw,filename=filename)
        # this is the part where I am trying to get the image back out
        collection = db.fs.files
        cursor = collection.find_one({"filename":"download (1).jpg"})
        response.content_type = 'image/jpeg'
        return cursor
    return "You missed a field."

修改

这将在浏览器中返回一个图像:

        # .... same as above
        # this is the part where I am trying to get the image back out
        thing = fs.get_last_version(filename=filename)
        response.content_type = 'image/jpeg'
        return thing

我剩下的问题是:

  • 为什么初始代码不起作用?
  • 如何将图像返回以便可以在图像标签中使用?
  • 返回图片时, 究竟返回了什么?浏览器正在解释的二进制数据?还有别的吗?
  • 图片是否包含chunks收藏文件的data字段中合并的fs.chunks

1 个答案:

答案 0 :(得分:2)

初始代码不起作用,因为您正在返回一个文档,PyMongo将其表示为Python字典。 Flask不知道该怎么做。 (注意,find_one()返回一个文档,find()返回一个Cursor。)

你的最终代码返回它从GridFS.get_last_version()获取的“东西”,它是一个GridOut对象,用于从GridFS文件中读取。

GridOut是可迭代的:迭代一个GridOut获得了多个字节。 Flask 确实知道如何将迭代转换为HTTP响应,因此代码的第二个版本可以正常工作。

本课程是:当您想要与GridFS交互时,请使用GridFS类而不是find()或find_one()。

是的,该图片包含来自chunks集合的合并fs.chunks数据。

要将图片包含在<img>标记中,此类内容应该有效:

@route('/images/<filename>')
def image(filename):
    fs = gridfs.GridFS(db)
    gridout = fs.get_last_version(filename=filename)
    response.content_type = 'image/jpeg'
    return gridout

然后在您的HTML中<img src="/images/filename.jpg">