2015-03-06 7 views
0

Предположим, что вид Flask-Admin ниже (примечание Я использую flask_wtf не wtforms). Я хотел бы загрузить файл csv, а затем на model_change, разобрать csv и сделать что-то в нем перед возвратом результата, который затем будет сохранен в модели. Тем не менее, я получаю ошибку: TypeError: coercing to Unicode: need string or buffer, FileField foundразобрать CSV в Flask-Admin/WTForms на model_change

from flask_wtf.file import FileField 

class myView(ModelView): 
    [...] 
    def scaffold_form(self): 
     form_class = super(myView, self).scaffold_form() 
     form_class.csv = FileField('Upload CSV') 
     return form_class 

    def on_model_change(self, form, model): 
     csv = form.csv 
     csv_data = self.parse_file(csv) 
     model.csv_data = csv_data 

    def parse_file(self, csv): 
     with open(csv, 'rb') as csvfile: 
      data = csv.reader(csvfile, delimiter=',') 

      for row in data: 
       doSomething() 

При доступе к csv.data, я получить <FileStorage: u'samplefile.csv' ('text/csv')>, но этот объект фактически не содержит данных в формате CSV в.

ответ

0

Хорошо, после углубления в модуль flask_wtf я смог найти достаточно, чтобы продолжить и получить обходное решение. FileField object имеет атрибут data, который обертывает класс werkzeug.datastructures.FileStorage, который предоставляет атрибут stream. Документы говорят, что это обычно указывает на открытый файловый ресурс, но поскольку я делаю это в памяти, в этом случае это буфер потока io.BytesIO object.

Попытка open():

with open(field.data.stream, 'rU') as csv_data: 
    [...] 

приведет к TypeError: coercing to Unicode: need string or buffer, _io.BytesIO found.

НО, csv.reader может также take a string or buffer directly, поэтому мы переходим в прямой стреляет буфер в csv.reader:

buffer = csv_field.data.stream # csv_field is the FileField obj 
csv_data = csv.reader(buffer, delimiter=',') 

for row in csv_data: 
    print row 

Я нашел, что это интересно, что если вам нужна дополнительная принуждение к/из Unicode UTF-8, примеры Csv в docs provides a snippet on wrapping an encoder/decoder.

0

Для меня это сделал трюк:

def on_model_change(self, form, model): 
     tweet_file = form.tweet_keywords_file 
     buffer = tweet_file.data.stream 
     file_data = buffer.getvalue()