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

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

问题描述

我正在尝试上传 CSV 文件,对其进行处理以生成结果,然后写回(下载)包含结果的新 CSV 文件.我对 Flask 非常陌生,我无法获得正确的" csv.reader 对象来进行迭代和处理.这是到目前为止的代码,

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)

终端输出为

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 对象时没有得到代表 2 行的 2 个列表,我做错了什么?

What am I doing wrong to not get 2 lists representing 2 rows when I iterate the csv.reader object?

推荐答案

好的,所以您的脚本存在一个主要问题,csv.reader 如前所述 here 需要一个文件对象或至少一个支持迭代器协议的对象.您正在传递一个 str ,它确实实现了迭代器协议,但它不是遍历行,而是遍历字符.这就是为什么你有你所做的输出.

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.

首先,它给出了一个单一字符 1csv.reader 将其视为具有一个字段的一行.之后 str 给出了另一个单个字符 ,csv.reader 将其视为具有两个空字段的行(因为逗号是字段分隔符).在整个 str 中一直如此,直到用完为止.

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.

解决方案(或至少一种解决方案)是将 str 转换为类似文件的对象.我尝试使用 flask.request.files["name"] 提供的流,但这不会遍历行.接下来,我尝试使用 cStringIO.StringIO 并且似乎有类似的问题.我结束了这个问题它在通用换行符模式下建议了一个 io.StringIO 对象,该对象有效.我最终得到了以下工作代码(也许它会更好):

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天全站免登陆