如何使用Python打开和处理存储在Google云端存储中的CSV文件

时间:2013-07-24 17:59:58

标签: python google-app-engine google-cloud-storage

我正在使用Google云端存储客户端库。

我正在尝试使用以下代码打开并处理CSV文件(已经上传到存储桶):

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

我得到错误&#34;参数1必须是迭代器&#34;响应csv.reader的第一个参数(即gcs_file)。显然gcs_file不支持迭代器.next方法。

有关如何进行的任何想法?我是否需要包装gcs_file并在其上创建迭代器或者是否有更简单的方法?

2 个答案:

答案 0 :(得分:3)

我认为你拥有自己的为csv.reader设计的包装器/迭代器会更好。如果gcs_file支持Iterator协议,则不清楚next()应该返回什么以始终容纳其使用者。

根据csv reader doc,它

  

返回一个读取器对象,它将迭代给定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, ''))

答案 1 :(得分: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文件支持迭代。