ValueError: I/O operation on closed file in Pyramid

ValueError: I/O operation on closed file in Pyramid

尝试通过 CSV 下载导出的数据时,终端返回错误。这不是一个简单的 x.read() 与 x.open() 问题,如 在类似的堆栈问题上,而是更棘手,因为它通过 Pyramid 和 Pyramid's Response 写入并保存到 csv 文件方法。

我对为什么会发生这种情况感到有点困惑,可以使用一些指导来查找错误。我感谢指导和建议。

Python2.7、金字塔


查看代码:

def export_results(request):
    response = Response(content_type='application/csv')
    results =  api.retrieve_assessment_results() #list retrieval of all results from db e.g. [<class(element, element)>, <class2(element, element)> ...]

    with NamedTemporaryFile(prefix='Export_%s' % datetime.now(),
        suffix='.csv', delete=True) as f:

        fileWriter = csv.writer(f, delimiter=',',quotechar='|', quoting=csv.QUOTE_MINIMAL)

        for a in results:
            print(a)
            fileWriter.writerow(['a.owner', 'a.assessment'])

        response.app_iter = f 
        response.headers['content_disposition'] = ('attachment; filename=Export.csv')

        return response

@view_config(route_name='analyst_view', renderer='templates/analyst_page.jinja2', request_method='GET', permission='read')
def analyst_view(request):
    #some other code 
    export = export_results(request)

    return {#other code, 'export': export}

终端错误:

 "/usr/local/lib/python2.7/site-packages/pyramid-1.5.7-py2.7.egg/pyramid/renderers.py", line 447, in render
    result = renderer(value, system_values)
  File "/usr/local/lib/python2.7/site-packages/pyramid_jinja2-2.5-py2.7.egg/pyramid_jinja2/__init__.py", line 265, in __call__
    return template.render(system)
  File "/usr/local/lib/python2.7/site-packages/jinja2/environment.py", line 969, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/lib/python2.7/site-packages/jinja2/environment.py", line 742, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/ack/code/venv/WEB/web/templates/analyst_page.jinja2", line 76, in top-level template code
    <div class="thumbnail"> <a href="{{export}}"><img src="{{request.static_url('web:static/img/book_bw.png')}}" width="2000" class="cards"/></a>
  File "build/bdist.macosx-10.10-x86_64/egg/webob/response.py", line 230, in __str__
    self.body
  File "build/bdist.macosx-10.10-x86_64/egg/webob/response.py", line 345, in _body__get
    body = b''.join(app_iter)
ValueError: I/O operation on closed file

通过从 with 块返回响应,您将在返回之前关闭 NamedTemporaryFile。您不想写入文件,而是写入 stream.

我在 Python3/Pyramid/SQLAlchemy 中使用了类似于下面的代码,它对我有用。没有安装 python 2,所以没有测试 python 2

import StringIO

f = StringIO.StringIO()

fileWriter = csv.writer(f, delimiter=',',quotechar='|',quoting=csv.QUOTE_MINIMAL)

for a in results:
    print(a)
    fileWriter.writerow(['a.owner', 'a.assessment'])

#rewind file
f.seek(0)
response = Response(
    request=request,
    content_disposition='attachment; filename="filename.csv"')
)
response.app_iter = f

return response