Python 使用Flask转换上载的CSV文件上载

Python 使用Flask转换上载的CSV文件上载,python,csv,flask,pythonanywhere,Python,Csv,Flask,Pythonanywhere,我在Python Anywhere上有一个简单的Flask应用程序。该应用程序提供了一个用户可以上传CSV文件的界面,该应用程序通过覆盖第一列(行[0])并将原始的行[0]放在文件末尾,将新列插入上传的CSV文件中,并为用户下载转换后的文件。因此,CSV输入如下所示(第一行是一个标题行,除了添加第四列名称外,该行不应修改): 输出应该如下所示: Pet1,Pet2,Pet3,Pet4 Birds,Dogs,Mice,Cats 这是我的密码: from flask import Flask, m

我在Python Anywhere上有一个简单的Flask应用程序。该应用程序提供了一个用户可以上传CSV文件的界面,该应用程序通过覆盖第一列(
行[0]
)并将原始的
行[0]
放在文件末尾,将新列插入上传的CSV文件中,并为用户下载转换后的文件。因此,CSV输入如下所示(第一行是一个标题行,除了添加第四列名称外,该行不应修改):

输出应该如下所示:

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
我可以看出我的脚本没有正确读取上传的输入文件(因此无法在我试图引用的列和
索引器中找到数据),但我还没有找到任何使用Python CSV库解析上传文件并以我需要的方式操作列的示例。我如何解决这个问题?任何指向正确方向的指点都将不胜感激

函数
csv.reader()
接受文件对象而不是文本。一种方法是保存文件,然后在transform函数中重新打开它

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()
从烧瓶导入烧瓶,做出响应,请求
进口经营者
输入io
导入csv
app=烧瓶(名称)
def transform():
将open('myfile.csv','rb')作为f:
读卡器=csv。读卡器(f)
全部=[]
行=下一个(读卡器)
行。追加('Pet4')
all.append(行)
对于读取器中的行:
pet4=行[0]
第[0]行=“鸟类”
行。追加(第4页)
all.append(行)
sortedlist=sorted(全部,键=operator.itemgetter(0))
返回分类列表
@应用程序路径(“/”)
def form():
返回“”
上载CSV文件
"""
@app.route('/transform',methods=[“POST”])
def transform_view():
request\u file=request.files['data\u file']
请求_file.save(“myfile.csv”)
如果没有请求\u文件:
返回“无文件”
#file_contents=io.StringIO(请求_file.stream.read().decode(“UTF8”),换行符=None)
#file\u contents=request\u file.stream.read().decode(“utf-8”)
结果=转换()
打印结果
响应=作出响应(结果)
response.headers[“内容处置”]=“附件;文件名=结果.csv”
返回响应
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
app.run()

正如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()
导入编解码器
进口经营者
从烧瓶进口烧瓶,做出响应,请求
导入csv
app=烧瓶(名称)
def转换(文本文件内容):
reader=csv.reader(文本文件内容)
列出所有=[]
行=下一个(读卡器)
行。追加('Pet4')
列出所有。追加(行)
对于读取器中的行:
pet4=行[0]
第[0]行=“鸟类”
行。追加(第4页)
列出所有。追加(行)
sortedlist=sorted(list_all,key=operator.itemgetter(0))
返回分类列表
@应用程序路径(“/”)
def form():
返回“”
上载CSV文件
"""
@app.route('/transform',methods=[“POST”])
def transform_view():
request\u file=request.files['data\u file']
如果没有请求\u文件:
返回“无文件”
stream=codecs.iterdecode(request_file.stream,'utf-8')
结果=转换(流)
响应=作出响应(str(结果))
response.headers[“内容处置”]=“附件;文件名=结果.csv”
返回响应
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
app.run()
根据问题,解决方案是执行
请求文件.read()
而不是
请求文件.stream.read()
。我自己从来没有这样做过,但它似乎对那个问题的操作有效。
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()