如何使用任务链接写入cloudstorage,blobstore Files API做得很好

时间:2014-10-04 22:33:25

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

使用blobstore File API,我可以编写非常大的blobfiles:

  • 创建blobfile
  • 从数据存储中读取数据并写入(追加)到blobstore文件
  • 将数据存储页面游标和blobstore文件传递给(下一个)任务
  • ....出于同样的目的使用其他任务
  • 并最终确定blobstore文件

现在使用GAE GCS客户端我无法追加并最终确定。如何在没有编写的情况下将非常大的文件写入GCS。撰写不是GCS客户端的一部分。 Files API仍然可以正常工作,但已被弃用。

使用任务链接在blobstore解决方案下面:

class BlobData(webapp2.RequestHandler):

    def post(self):

        page = int(self.request.get('page', default_value='0'))
        data = Data.get_data(.....)

        blob_file = self.request.get('blobfile', default_value='none')
        if blob_file == 'none':
            file_name = files.blobstore.create(mime_type='text/...',
                                               _blobinfo_uploaded_filename='data....txt')
        else:
            data.with_cursor(self.request.get('cursor'))

        count = 0  # page lines counter
        with files.open(blob_file, 'a') as f:
            for each in data.fetch(page):
                f.write(each)
                count += 1

        if count >= page:
            cursor = data.cursor()
            taskqueue.add(url='/blobdata', queue_name='blobdata', countdown=10, method='POST',
                          params={'page': page, 'cursor': cursor, 'blobfile': blob_file},
                          headers={'X-AppEngine-FailFast': 'True'})
        else:  # no data left
            files.finalize(blob_file)

1 个答案:

答案 0 :(得分:2)

在Java客户端中,我们可以序列化读取通道(相当于Python客户端中的缓冲区),并将其传递给另一个任务以继续写入同一文件。有关详细信息,请参阅the Java doc

  

用于将数据读取到Google云端存储的可读字节通道。   此类的实现可以在内部缓冲数据以减少   远程呼叫。

     

此类是Serializable,允许   读取文件的一部分,序列化GcsInputChannel反序列化   它,并继续从同一位置读取同一文件。

我不知道Python GCS客户端返回的缓冲区是否可以序列化,我在文档中找不到任何信息,但可能值得检查。

如果那是不可能的,那么使用构图。不要担心组合在GCS客户端中不可用,您始终可以使用App Engine中的标准Cloud Storage API库。 API文档在Python here中有一个compose示例。它看起来像这样:

composite_object_resource = {
        'contentType': 'text/plain',  # required
        'contentLanguage': 'en',
        'metadata': {'my-key': 'my-value'},
}
compose_req_body = {
        'sourceObjects': [
                {'name': source_object_name_1,
                 'objectPreconditions': {'ifGenerationMatch': source_generation_1}},
                {'name': source_object_name_2,
                 'objectPreconditions': {'ifGenerationMatch': source_generation_2}}],
        'destination': composite_object_resource
}
req = client.objects().compose(
        destinationBucket=bucket_name,
        destinationObject=composite_object_name,
        body=compose_req_body)
resp = req.execute()
print json.dumps(resp, indent=2)