【问题标题】:ValueError: I/O operation on closed file in PyramidValueError:对 Pyramid 中已关闭文件的 I/O 操作
【发布时间】:2016-06-13 00:57:16
【问题描述】:

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

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

Python 2.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

【问题讨论】:

    标签: python csv pyramid temporary-files temporary-directory


    【解决方案1】:

    通过从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
    

    【讨论】:

    • 我收到一个错误:File "/Users/ack/code/venv/WEB/web/views/default.py", line 104, in analyst_view export = export_results(request) File "/Users/ack/code/venv/WEB/nweb/views/default.py", line 83, in export_results fileWriter.writerow([a.owner, a.assessment]) TypeError: unicode argument expected, got 'str'
    • 我现在看到你使用的是 Python 2.7,所以语法也有​​点不同。如果这不起作用,请检查this question。也许考虑升级到 python 3 ;)
    • 由于某种原因,这导致导出按钮出现 404 Not Found 错误:404 Not Found The resource could not be found. /users/200 OKContent-Type: application/csvcontent_disposition: attachment; filename=Export.csvContent-Length: 41547|&lt;Assessment_Result(owner='&lt;User(username ='dance', 017f', firstname ='Jennny', lastname ='CadsfFD', email='dancegirl@aol.com', institution='None', residency_year='None')&gt;', AND MORE code.... 所以它可以打印,但在点击button 时不会导出为文件。
    • 我明天可以看看我之前是如何解决这个问题的,但与此同时,请看这里:docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/…
    • 想通了!导出的问题是我需要在此链接底部显示的Renderer 和View_Config:docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/…。我在函数export_results 的顶部添加了这个:@view_config(route_name='data', renderer='csv') 以及一个新的route。谢谢 Thijs!
    猜你喜欢
    • 2013-09-27
    • 2016-07-21
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多