如何通过 PyMongo 和 Bottle 显示来自 MongoDB 数据库的图像?
Posted
技术标签:
【中文标题】如何通过 PyMongo 和 Bottle 显示来自 MongoDB 数据库的图像?【英文标题】:How to display an image from MongoDB database via PyMongo and Bottle? 【发布时间】:2014-01-31 22:52:56 【问题描述】:期望的行为
将图像上传到 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
我剩下的问题是:
为什么初始代码不起作用? 如何将图片退回,以便在图片标签中使用? 返回图像时,返回的究竟是什么?浏览器正在解释的二进制数据?还有什么? 图像是否由fs.chunks
集合文档的data
字段中合并的chunks
组成?
【问题讨论】:
【参考方案1】:初始代码不起作用,因为您要返回一个文档,PyMongo 将其表示为 Python 字典。 Flask 不知道如何处理它。 (注意 find_one() 返回单个文档,find() 返回 Cursor。)
您的最终代码返回它从 GridFS.get_last_version() 获得的“事物”,这是一个用于从 GridFS 文件中读取的 GridOut 对象。
GridOut 是可迭代的:迭代 GridOut 会获得大量的字节。 Flask确实知道如何将可迭代对象转换为 HTTP 响应,因此您的代码的第二个版本可以工作。
教训是:当你想与 GridFS 交互时,使用 GridFS 类而不是 find() 或 find_one()。
是的,图像由来自fs.chunks
集合的合并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">
。
【讨论】:
感谢您提供的信息。早些时候,我提出了一个关于<img>
标签实现的更具体的问题。它遵循与您上面的建议相同的逻辑,但它为图像返回 404。这个问题在这里:***.com/questions/21117166/…以上是关于如何通过 PyMongo 和 Bottle 显示来自 MongoDB 数据库的图像?的主要内容,如果未能解决你的问题,请参考以下文章
将项目附加到 PyMongo 中的 MongoDB 文档数组而不重新插入
最近学python和bottle框架,用sqlite3,网页中文显示乱码,咋办捏?
如何使用 PyMongo 在 MongoDB 中获取不同的名称和计数