Загрузите и проанализируйте CSV-файл с помощью Google App Engine

Мне интересно, может ли кто-нибудь с лучшим пониманием python и gae помочь мне в этом. Я загружаю файл csv из формы в хранилище gae.

class CSVImport(webapp.RequestHandler): def post(self): csv_file = self.request.get('csv_import') fileReader = csv.reader(csv_file) for row in fileReader: self.response.out.write(row) 

Я столкнулся с той же проблемой, о которой упоминает кто-то другой – http://groups.google.com/group/google-appengine/browse_thread/thread/bb2d0b1a80ca7ac2/861c8241308b9717

То есть, csv.reader выполняет итерацию по каждому символу, а не по строке. Инженер Google оставил это объяснение:

Вызов self.request.get ('csv') возвращает строку. Когда вы перебираете строку, вы перебираете символы, а не строки. Вы можете увидеть разницу здесь:

  class ProcessUpload(webapp.RequestHandler): def post(self): self.response.out.write(self.request.get('csv')) file = open(os.path.join(os.path.dirname(__file__), 'sample.csv')) self.response.out.write(file) # Iterating over a file fileReader = csv.reader(file) for row in fileReader: self.response.out.write(row) # Iterating over a string fileReader = csv.reader(self.request.get('csv')) for row in fileReader: self.response.out.write(row) 

Я действительно не следую объяснениям и безуспешно выполнял это. Может ли кто-нибудь дать более четкое объяснение этому и предлагаемое решение?

Спасибо, август

  • Как получить корневой путь приложения в GAE
  • Группа GAE / модель данных для согласованности и производительности
  • Механизм не работает для автоматизации входа в Gmail в Google Appengine
  • Получение выбранного значения из раскрывающегося списка в формате html без отправки
  • Flask vs webapp2 для Google App Engine
  • Google App Engine Python Webapp2 301 перенаправляет с www на домен без www
  • App Engine: структурированное свойство vs Ссылка для отношения «один ко многим»
  • Как отправить строку, не связанную с английским юникодом, с помощью HTTP-заголовка?
  • 3 Solutions collect form web for “Загрузите и проанализируйте CSV-файл с помощью Google App Engine”

    Короткий ответ, попробуйте следующее:

     fileReader = csv.reader(csv_file.split("\n")) 

    Долгий ответ, рассмотрите следующее:

     for thing in stuff: print thing.strip().split(",") 

    Если материал является указателем на файл, каждая вещь является строкой. Если материал является списком, каждая вещь является предметом. Если материал – это строка, каждая вещь является символом.

    Итерация над объектом, возвращаемым csv.reader, приведет к поведению, аналогичному итерации по переданному объекту, только с каждым элементом CSV-анализа. Если вы перебираете строку, вы получите CSS-разборную версию каждого символа.

    Я не могу придумать более четкое объяснение, чем то, о чем говорил инженер Google, о котором вы говорили. Так что давайте немного разобьем его.

    Модуль csv Python работает с файлоподобными объектами, то есть файлом или чем-то, что ведет себя как файл Python. Следовательно, csv.reader () ожидает получить файл-объект, поскольку это только требуемый параметр.

    webapp.RequestHandler запроса webapp.RequestHandler обеспечивает доступ к параметрам HTTP, которые отправляются в форме. В HTTP параметры публикуются как пары ключ-значение, например, csv=record_one,record_two . Когда вы вызываете self.request.get('csv') это возвращает значение, связанное с ключом csv как строку Python. Строка Python не является файлоподобным объектом. По-видимому, модуль csv когда он не понимает объект и просто выполняет его итерацию (в Python строки могут быть повторены символом, например, for c in 'Test String': print c будет печатать каждый символ в строка на отдельной строке).

    К счастью, Python предоставляет класс StringIO, который позволяет обрабатывать строку как файл-подобный объект. Итак, (если GAE поддерживает StringIO, и нет причин, по которым это не должно быть), вы должны иметь возможность сделать это:

     class ProcessUpload(webapp.RequestHandler): def post(self): self.response.out.write(self.request.get('csv')) # Iterating over a string as a file stringReader = csv.reader(StringIO.StringIO(self.request.get('csv'))) for row in stringReader: self.response.out.write(row) 

    Это будет работать так, как вы ожидаете.

    Редактировать Я предполагаю, что вы используете что-то вроде <textarea/> для сбора файла csv. Если вы загружаете вложение, может потребоваться различная обработка (я не так хорошо знаком с Python GAE или как он обрабатывает вложения).

    Вам нужно вызвать csv_file = self.request.POST.get("csv_import") а не csv_file = self.request.get("csv_import") .

    Второй вариант дает вам строку, указанную в исходном посте. Но доступ через self.request.POST.get дает вам объект cgi.FieldStorage .

    Это означает, что вы можете вызвать csv_file.filename чтобы получить имя файла объекта и csv_file.type чтобы получить csv_file.type . Кроме того, если вы используете csv_file.file , это объект StringO (объект только для чтения из модуля StringIO ), а не только строка. Как упоминал ig0774 в своем ответе , модуль StringIO позволяет обрабатывать строку как файл.

    Поэтому ваш код может просто быть:

     class CSVImport(webapp.RequestHandler): def post(self): csv_file = self.request.POST.get('csv_import') fileReader = csv.reader(csv_file.file) for row in fileReader: # row is now a list containing all the column data in that row self.response.out.write(row) 
    Python - лучший язык программирования в мире.