无法解析使用Flask上传的.csv文件 [英] Not able to parse a .csv file uploaded using Flask

查看:209
本文介绍了无法解析使用Flask上传的.csv文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图上传一个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行的错误?

csv.reader 如这里需要一个文件对象或至少一个支持迭代器协议的对象。你正在传递一个实现了迭代器协议的 str ,但是不是迭代遍历行,而是遍历字符。这就是为什么你有输出。



首先,它给出一个单独的字符 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 =真)


I am trying to 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)

The terminal output being

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']

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, 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.

First, it gives a singe character 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.

The solution (or at least one solution) is to turn the 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)

这篇关于无法解析使用Flask上传的.csv文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆