问题
I have an upload form that accepts a zip file and has a method that unzips it and get each file from it. Make a unique id from the md5 hash of it and stores them in a dictionary;
dict[uid] = imagebinary
and returns it so that the form can store them into ZODB. I can't store the image just like that, as this error spits out;
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)
So, how should I go about doing that? I'm pretty much stuck on this.
回答1:
The error you see is unrelated to image storing in the ZODB.
To store larger pieces of data, you really want to use a ZODB Blob
instead of putting the image data directly in an attribute. Blob
s are stored separately on disk and do not flush the ZODB cache, and can be streamed back to the client on access again.
To create and store a Blob
, use:
from ZODB.blob import Blob
uid = Blob(imagebinary.read())
Once created like that, you can later use uid
as a file; you need to open it in read or write mode first. To return the contents of the blob from a view, for example, use:
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
Blobs are bound to transactions and changes to them are automatically discarded if the transaction is rolled back.
来源:https://stackoverflow.com/questions/14613206/pyramid-zodb-image-storing