我在Python Anywhere上托管了一个简单的Flask应用。该应用程序提供了一个界面,用户可以在其中上传CSV文件,并通过覆盖第一列(row[0]
)并将原始row[0]
放在末尾,将新列插入上载的CSV文件中。文件,然后为用户下载转换后的文件。因此,CSV输入看起来像这样(第一行是标头行,除了添加第4列名称外,应保持不变):
Pet1,Pet2,Pet3
Cats,Dogs,Mice
输出应如下所示:
Pet1,Pet2,Pet3,Pet4
Birds,Dogs,Mice,Cats
这是我的代码:
from flask import Flask, make_response, request
import operator
import io
import csv
app = Flask(__name__)
def transform(text_file_contents):
reader = csv.reader(text_file_contents)
all = []
row = next(reader)
row.append('Pet4')
all.append(row)
for row in reader:
pet4 = row[0]
row[0] = "Birds"
row.append(pet4)
all.append(row)
sortedlist = sorted(all, key=operator.itemgetter(0))
return sortedlist
@app.route('/')
def form():
return """
<html>
<body>
<h1>Upload a CSV File</h1>
<form action="/transform" method="post" enctype="multipart/form-data">
<input type="file" name="data_file" />
<input type="submit" />
</form>
</body>
</html>
"""
@app.route('/transform', methods=["POST"])
def transform_view():
request_file = request.files['data_file']
if not request_file:
return "No file"
file_contents = request_file.stream.read().decode("utf-8")
result = transform(file_contents)
response = make_response(result)
response.headers["Content-Disposition"] = "attachment; filename=result.csv"
return response
这是我得到的错误:
Traceback (most recent call last):
File "/home/user/.virtualenvs/myvirtualenv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/home/user/.virtualenvs/myvirtualenv/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/user/.virtualenvs/myvirtualenv/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/user/.virtualenvs/myvirtualenv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/home/user/.virtualenvs/myvirtualenv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/home/user/.virtualenvs/myvirtualenv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/user/mysite/callnumbers.py", line 62, in transform_view
result = transform(file_contents)
File "/home/user/mysite/callnumbers.py", line 18, in transform
row[0] = row[1]
IndexError: list index out of range
我可以确定我的脚本未正确读取上载的输入文件(因此无法在我要引用的列和IndexError
中找到数据),但我却无法使用Python CSV库查找Flask的任何示例,以解析上传的文件并按我需要的方式操作列。我该如何解决?任何指向正确方向的指针都将受到赞赏!
答案 0 :(得分:0)
csv.reader()
函数采用文件对象而不是文本。一种方法是保存文件,然后在转换函数中重新打开它。
from flask import Flask, make_response, request
import operator
import io
import csv
app = Flask(__name__)
def transform():
with open('myfile.csv', 'rb') as f:
reader = csv.reader(f)
all = []
row = next(reader)
row.append('Pet4')
all.append(row)
for row in reader:
pet4 = row[0]
row[0] = "Birds"
row.append(pet4)
all.append(row)
sortedlist = sorted(all, key=operator.itemgetter(0))
return sortedlist
@app.route('/')
def form():
return """
<html>
<body>
<h1>Upload a CSV File</h1>
<form action="/transform" method="post" enctype="multipart/form-data">
<input type="file" name="data_file" />
<input type="submit" />
</form>
</body>
</html>
"""
@app.route('/transform', methods=["POST"])
def transform_view():
request_file = request.files['data_file']
request_file.save("myfile.csv")
if not request_file:
return "No file"
#file_contents = io.StringIO(request_file.stream.read().decode("UTF8"), newline=None)
#file_contents = request_file.stream.read().decode("utf-8")
result = transform()
print result
response = make_response(result)
response.headers["Content-Disposition"] = "attachment; filename=result.csv"
return response
if __name__ == '__main__':
app.run()
答案 1 :(得分:0)
正如Mike C.所说,问题是csv.reader()函数采用文件对象(或等效文件)代替文本。但是,您无需在磁盘上保存文件,而可以在流上解码:
stream = codecs.iterdecode(request_file.stream, 'utf-8')
result = transform(stream)
完整的代码:
import codecs
import operator
from flask import Flask, make_response, request
import csv
app = Flask(__name__)
def transform(text_file_contents):
reader = csv.reader(text_file_contents)
list_all = []
row = next(reader)
row.append('Pet4')
list_all.append(row)
for row in reader:
pet4 = row[0]
row[0] = "Birds"
row.append(pet4)
list_all.append(row)
sortedlist = sorted(list_all, key=operator.itemgetter(0))
return sortedlist
@app.route('/')
def form():
return """
<html>
<body>
<h1>Upload a CSV File</h1>
<form action="/transform" method="post" enctype="multipart/form-data">
<input type="file" name="data_file" />
<input type="submit" />
</form>
</body>
</html>
"""
@app.route('/transform', methods=["POST"])
def transform_view():
request_file = request.files['data_file']
if not request_file:
return "No file"
stream = codecs.iterdecode(request_file.stream, 'utf-8')
result = transform(stream)
response = make_response(str(result))
response.headers["Content-Disposition"] = "attachment; filename=result.csv"
return response
if __name__ == '__main__':
app.run()