Pyramid + ZODB 图像存储

1 投票
1 回答
1120 浏览
提问于 2025-04-17 14:14

我有一个上传表单,可以接受一个压缩文件(zip文件),并且有一个方法可以解压这个文件,获取里面的每一个文件。然后我会用这些文件的md5哈希值生成一个唯一的ID,并把它们存储在一个字典里。

dict[uid] = imagebinary

接着,这个方法会返回这些ID,以便表单可以把它们存储到ZODB数据库中。不过,我不能直接存储这些图片,因为这样会出现一个错误:

    2013-01-31 08:59:59,061 ERROR [waitress][Dummy-5] Exception when serving /
Traceback (most recent call last):
  File "/home/maverick/inigo/sources/devenv/lib/python2.7/site-packages/waitress-0.8.2-py2.7.egg/waitress/channel.py", line 329, in service
    task.service()
  File "/home/maverick/inigo/sources/devenv/lib/python2.7/site-packages/waitress-0.8.2-py2.7.egg/waitress/task.py", line 173, in service
    self.execute()
  File "/home/maverick/inigo/sources/devenv/lib/python2.7/site-packages/waitress-0.8.2-py2.7.egg/waitress/task.py", line 380, in execute
    app_iter = self.channel.server.application(env, start_response)
  File "/home/maverick/.buildout/eggs/pyramid-1.4-py2.7.egg/pyramid/router.py", line 251, in __call__
    response = self.invoke_subrequest(request, use_tweens=True)
  File "/home/maverick/.buildout/eggs/pyramid-1.4-py2.7.egg/pyramid/router.py", line 227, in invoke_subrequest
    response = handle_request(request)
  File "/home/maverick/inigo/sources/devenv/lib/python2.7/site-packages/pyramid_debugtoolbar-1.0.4-py2.7.egg/pyramid_debugtoolbar/toolbar.py", line 133, in toolbar_tween
    body = tb.render_full(request).encode('utf-8', 'replace')
  File "/home/maverick/inigo/sources/devenv/lib/python2.7/site-packages/pyramid_debugtoolbar-1.0.4-py2.7.egg/pyramid_debugtoolbar/tbtools.py", line 240, in render_full
    summary = self.render_summary(include_title=False, request=request)
  File "/home/maverick/inigo/sources/devenv/lib/python2.7/site-packages/pyramid_debugtoolbar-1.0.4-py2.7.egg/pyramid_debugtoolbar/tbtools.py", line 229, in render_summary
    'description':  description_wrapper % escape(self.exception),
UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 114: ordinal not in range(128)

那么,我该怎么做呢?我现在有点卡住了。

1 个回答

3

你看到的这个错误和在ZODB中存储图片没有关系。

如果你想存储更大的数据,最好使用ZODB的Blob,而不是直接把图片数据放在一个属性里。Blob会单独存储在硬盘上,不会影响ZODB的缓存,而且可以在需要的时候再传回给客户端。

要创建和存储一个Blob,可以使用:

from ZODB.blob import Blob

uid = Blob(imagebinary.read())

一旦这样创建了Blob,你可以以后用uid来当作文件使用;不过你需要先以读或写的模式打开它。如果你想从一个视图中返回这个blob的内容,可以使用:

from pyramid.response import Response

def serveimage(request):
    # retrieve uid from somewhere
    resp = Response(content_type='image/jpeg')
    resp.app_iter = uid.open('r')  # open for reading
    return resp

Blob和事务是绑定在一起的,如果事务被回滚,对Blob的任何更改都会自动被丢弃。

撰写回答