无法解析使用Flask上传的.csv文件 [英] Not able to parse a .csv file uploaded using Flask
问题描述
我试图上传一个CSV文件
,在产生结果
并写回(下载)包含结果的新CSV文件
。
我是Flask的新手,我无法得到一个正确的 csv.reader
对象来迭代和处理
。代码至今
__ author__ ='shivendra'
from flask import烧瓶,make_response,请求
import csv
$ b $ app = Flask(__ name__)
def transform(text_file_contents):
return text_file_contents.replace(=,,)
@ app.route('/')
def form():
return
< html>
< body>
< h1>转换文件演示< / h1>
< form action =/ transformmethod =postenctype =multipart / form-data>
< input type =filename =data_file/>
< input type =submit/>
< / form>
< / body> ;
< / html>
@ app.route('/ transform',methods = [POST])
de f transform_view():
file = request.files ['data_file']
如果不是文件:
返回没有文件
file_contents = file.stream。 read()。decode(utf-8)
csv_input = csv.reader(file_contents)
print(file_contents)
print(type(file_contents))
print(csv_input )
for csv_input中的行:
print(row)
result = transform(file_contents)
response = make_response(result)
response.headers [Content-Disposition] =attachment; filename = result.csv
返回响应
$ b $ if if __name__ ==__main__:
app.run(host ='0.0.0.0',port = 5001,debug =真)
终端输出是
127.0.0.1 - - [12 / Oct / 2015 02:51:53]GET / HTTP / 1.1200 -
127.0.0.1 - - [12 / Oct / 2015 02:51:59POST / transform HTTP / 1.1200 -
4,5,6
< class'str'>
< _csv.reader object at 0x105149438>
['1']
['','']
['2']
['','']
['3']
[]
['4']
['','']
['5']
['','']
[ '6']
鉴于我读取的文件是
我在做迭代csv.reader对象时没有得到2个表示2行的错误?
str
,但是不是迭代遍历行,而是遍历字符。这就是为什么你有输出。 首先,它给出一个单独的字符 解决方案(或者至少有一个解决方案)是把 I am trying to The terminal output being Whereas the file I read is
What am I doing wrong to not get 2 lists representing 2 rows when I iterate the csv.reader object? OK, so there is one major problem with your script, First, it gives a singe character The solution (or at least one solution) is to turn the
这篇关于无法解析使用Flask上传的.csv文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! 1
, csv.reader
看作是一个字段的行。之后, str
给出另外一个字符,,
csv.reader
看作是一个有两个空字段的行(因为逗号是字段分隔符)。它在整个 str
中都是这样,直到耗尽为止。
str
变成一个类似文件的对象。我尝试使用由 flask.request.files [name]
提供的流,但是这不会遍历行。接下来,我尝试使用 cStringIO.StringIO
,这似乎有一个类似的问题。我结束了这个问题其中建议使用通用换行模式的 io.StringIO
对象。我结束了以下工作代码(也许它可能会更好):
$ p $ __ author__ ='shivendra'
从烧瓶导入烧瓶,make_response,请求
导入io
导入csv
app =烧瓶(__ name__)
def transform(text_file_contents):
返回text_file_contents.replace(=,,)
@ app.route('/')
def form():
return
< html>
< body>
< h1>转换文件演示< / h1>
< form action =/ transform method =postenctype =multipart / form-data>
< input type =filename =data_file/>
< input type =submit/ >
< / form>
< / body>
< / html>
@ app.route / transform',methods = [POST])
def transform_view():
f = request.files ['data_file ]
如果不是f:
返回无文件
stream = io.StringIO(f.stream.read()。decode(UTF8),newline = None )
csv_input = csv.reader(stream)
#print(file contents:,file_contents)
#print(type(file_contents))
print(csv_input)$ b (b)
$ b response = make_response(result)
response.headers [Content-Disposition] =attachment; filename = result.csv
返回响应
$ b $ if if __name__ ==__main__:
app.run(host ='0.0.0.0',port = 5001,debug =真)
upload a CSV file
, work on it to produce results
and write back (download) a new CSV file containing the result
.
I am very new to Flask and I am not able to get a "proper" csv.reader
object to iterate and work upon
Here is the code so far__author__ = 'shivendra'
from flask import Flask, make_response, request
import csv
app = Flask(__name__)
def transform(text_file_contents):
return text_file_contents.replace("=", ",")
@app.route('/')
def form():
return """
<html>
<body>
<h1>Transform a file demo</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():
file = request.files['data_file']
if not file:
return "No file"
file_contents = file.stream.read().decode("utf-8")
csv_input = csv.reader(file_contents)
print(file_contents)
print(type(file_contents))
print(csv_input)
for row in csv_input:
print(row)
result = transform(file_contents)
response = make_response(result)
response.headers["Content-Disposition"] = "attachment; filename=result.csv"
return response
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5001, debug=True)
127.0.0.1 - - [12/Oct/2015 02:51:53] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [12/Oct/2015 02:51:59] "POST /transform HTTP/1.1" 200 -
4,5,6
<class 'str'>
<_csv.reader object at 0x105149438>
['1']
['', '']
['2']
['', '']
['3']
[]
['4']
['', '']
['5']
['', '']
['6']
csv.reader
as noted here expects a file object or at least an object which supports the iterator protocol. You are passing a str
which does implement the iterator protocol, but instead of iterating through the lines, it iterates through the characters. This is why you have the output you do.1
which the csv.reader
sees as a line with one field. After that the str
gives another single character ,
which the csv.reader
sees as a line with two empty fields (since the comma is the field seperator). It goes on like that throughout the str
until it's exhausted.str
into a file-like object. I tried using the stream provided by flask.request.files["name"]
, but that doesn't iterate through the lines. Next, I tried using a cStringIO.StringIO
and that seemed to have a similar issue. I ended up at this question which suggested an io.StringIO
object in universal newlines mode which worked. I ended up with the following working code (perhaps it could be better):__author__ = 'shivendra'
from flask import Flask, make_response, request
import io
import csv
app = Flask(__name__)
def transform(text_file_contents):
return text_file_contents.replace("=", ",")
@app.route('/')
def form():
return """
<html>
<body>
<h1>Transform a file demo</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():
f = request.files['data_file']
if not f:
return "No file"
stream = io.StringIO(f.stream.read().decode("UTF8"), newline=None)
csv_input = csv.reader(stream)
#print("file contents: ", file_contents)
#print(type(file_contents))
print(csv_input)
for row in csv_input:
print(row)
stream.seek(0)
result = transform(stream.read())
response = make_response(result)
response.headers["Content-Disposition"] = "attachment; filename=result.csv"
return response
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5001, debug=True)