2013-07-24 2 views
3

Я использую клиентскую библиотеку Google Cloud Storage.Как открыть и обработать файл CSV, хранящийся в облачном хранилище Google, используя Python

Я пытаюсь открыть и обрабатывать CSV-файл (который был уже загружен на ведро), используя такой код:

filename = '/<my_bucket/data.csv' 
with gcs.open(filename, 'r') as gcs_file: 
    csv_reader = csv.reader(gcs_file, delimiter=',', quotechar='"') 

Я получаю ошибку «аргумент 1 должен быть итератор» в ответ на первый аргумент csv.reader (т. е. gcs_file). По-видимому, gcs_file не поддерживает метод iterator .next.

Любые идеи о том, как действовать? Нужно ли обертывать gcs_file и создавать на нем итератор или есть более простой способ?

ответ

3

Я думаю, что лучше у вас есть собственный обертер/итератор, предназначенный для csv.reader. Если gcs_file должен был поддерживать протокол Iterator, неясно, какой следующий() должен возвращать, чтобы всегда вместить его потребителя.

Согласно Csv читателя документ, он

Вернуть объект читателя, который будет перебирать строки в данной csvfile. csvfile может быть любым объектом, который поддерживает протокол итератора и возвращает строку каждый раз при вызове метода next() - оба объекта - объекты файлов и объекты списка. Если csvfile является файловым объектом, он должен быть открыт с флагом 'b' на платформах, где это имеет значение.

Он ожидает фрагмент необработанных байтов из основного файла, не обязательно строку. Вы можете иметь оболочку, как это (не проверено):

class CsvIterator(object) 
    def __init__(self, gcs_file, chunk_size): 
    self.gcs_file = gcs_file 
    self.chunk_size = chunk_size 
    def __iter__(self): 
    return self 
    def next(self): 
    result = self.gcs_file.read(size=self.chunk_size) 
    if not result: 
     raise StopIteration() 
    return result 

Ключ должен прочитать кусок в то время, так что, когда у вас есть большой файл, вы не взрывают память или опыт тайм-аут от UrlFetch ,

Или даже проще. Использовать iter встроенный:

csv.reader(iter(gcs_file.readline, '')) 
+0

Я использую 'csv_reader_reader = csv.reader (iter (gcs_file.readline, ''), delimiter = ',', quotechar = '"') 'и он работает хорошо. – philipfc

+0

Исправлено. Обратите внимание на некоторые изменения, прежде чем требуется 183 SDK. Https://code.google.com/p/appengine-gcs-client/source/list – Yey

1

Попробуйте это:

from StringIO import StringIO 
filename = '/<my_bucket/data.csv' 
with gcs.open(filename, 'r') as gcs_file: 
    csv_reader = csv.reader(StringIO(gcs_file.read()), delimiter=',', 
          quotechar='"') 

Это не идеально, хотя. Я подал запрос функции, чтобы файлы GCS поддерживали итерацию.

+0

Благодарим за отправку запроса на функцию. Я думаю, что использование встроенного объекта iter хорошо работает. Спасибо также за идею StringIO. – philipfc

+0

Я предлагаю использовать cSTringIO, который быстрее – marcadian