从云函数在 Google Cloud Storage 中创建新的 csv 文件

2024-05-08

第一次使用 Google 云存储。下面我有一个云函数,每当 csv 文件上传到时就会触发该函数my-folder在我的桶里。我的目标是在同一文件夹中创建一个新的 csv 文件,读取上传的 csv 的内容并将每一行转换为将进入新创建的 csv 的 URL。问题是我遇到了麻烦creating首先是新的 csv,更不用说实际写入它了。

My code:

import os.path
import csv
import sys
import json
from csv import reader, DictReader, DictWriter
from google.cloud import storage
from io import StringIO

def generate_urls(data, context):
    if context.event_type == 'google.storage.object.finalize':
        storage_client = storage.Client()
        bucket_name = data['bucket']
        bucket = storage_client.get_bucket(bucket_name)
        folder_name = 'my-folder'
        file_name = data['name']

        if not file_name.endswith('.csv'):
            return

接下来的几行来自一个例子 https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/storage/cloud-client/storage_compose_file.py在 GCP 的 GitHub 存储库中。这是我期望创建新的 csv 的时候,但什么也没有发生。

        # Prepend 'URL_' to the uploaded file name for the name of the new csv
        destination = bucket.blob(bucket_name + '/' + file_name[:14] + 'URL_' + file_name[14:])
        destination.content_type = 'text/csv'
        sources = [bucket.get_blob(file_name)]
        destination.compose(sources)
        output = bucket_name + '/' + file_name[:14] + 'URL_' + file_name[14:]


        # Transform uploaded csv to string - this was recommended on a similar SO post, not sure if this works or is the right approach...
        blob = bucket.blob(file_name)
        blob = blob.download_as_string()
        blob = blob.decode('utf-8')
        blob = StringIO(blob)

        input_csv = csv.reader(blob)

下一行是我收到错误的地方:No such file or directory: 'myProjectId/my-folder/URL_my_file.csv'

        with open(output, 'w') as output_csv:
            csv_dict_reader = csv.DictReader(input_csv, )
            csv_writer = csv.DictWriter(output_csv, fieldnames=['URL'], delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
            csv_writer.writeheader()
            line_count = 0
            for row in csv_dict_reader:
                line_count += 1
                url = ''
                ...
                # code that converts each line
                ...
                csv_writer.writerow({'URL': url})
            print(f'Total rows: {line_count}')

如果有人对我如何创建新的 csv 然后写入它有任何建议,这将是一个巨大的帮助。谢谢你!


我可能会说我对代码和解决方案的设计有一些疑问:

  1. 据我了解 - 一方面,云功能是由finalise event 谷歌云存储触发器 https://cloud.google.com/functions/docs/calling/storage,而不是另一方面,您想将新创建的文件保存到同一个存储桶中。成功后,该存储桶中出现新对象将触发云函数的另一个实例。这是预期的行为吗?您的云功能准备好了吗?

  2. 从本体论上来说,不存在这样的东西folder。因此在这段代码中:

        folder_name = 'my-folder'
        file_name = data['name']

第一行有点多余,除非您想将该变量和值用于其他用途......并且file_name获取包括所有前缀的对象名称(您可以将它们视为“文件夹”。

  1. 你提到的例子 -storage_compose_file.py https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/storage/cloud-client/storage_compose_file.py- 是关于如何将 GCS 中的几个对象组合成一个。我不确定该示例是否与您的情况相关,除非您有一些额外的要求。

  2. 现在,让我们看一下这个片段:

        destination = bucket.blob(bucket_name + '/' + file_name[:14] + 'URL_' + file_name[14:])
        destination.content_type = 'text/csv'
        sources = [bucket.get_blob(file_name)]
        destination.compose(sources)

a. bucket.blob- 是一个工厂构造函数 - 请参阅API 存储桶说明 https://googleapis.dev/python/storage/latest/buckets.html。我不确定您是否真的想使用bucket_name作为其论证的一个要素......

b. sources- 成为仅包含一个元素的列表 - 对 GCS 存储桶中现有对象的引用。

c. destination.compose(sources)- 是否尝试复制现有对象?如果成功 - 它可能会触发您的云功能的另一个实例。

  1. 关于类型变更
        blob = bucket.blob(file_name)
        blob = blob.download_as_string()

第一行之后blob变量具有类型google.cloud.storage.blob.Blob。第二次之后——bytes。我认为 Python 允许这样的事情......但你真的喜欢它吗?在。。之间download_as_string方法已弃用 - 请参阅Blob/对象 API https://googleapis.dev/python/storage/latest/blobs.html

  1. 有关output:
   output = bucket_name + '/' + file_name[:14] + 'URL_' + file_name[14:]
    
   with open(output, 'w') as output_csv:

请记住 - 所有这些都发生在云函数的内存中。与 GCS 的 blob 桶无关。如果您想在云功能中使用临时文件 - 您将在/tmp目录 -从 Google Cloud Function 写入临时文件 https://stackoverflow.com/questions/42719793/write-temporary-files-from-google-cloud-function我猜你会因为这个问题而收到错误。

=> 提出一些建议。

您可能希望将对象下载到云函数内存中(下载到/tmp目录)。然后您想处理源文件并将结果保存在源附近。然后您想将结果上传到another(不是来源)桶。如果我的假设是正确的,我建议一步一步地实施这些事情,并检查每一步是否得到了预期的结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从云函数在 Google Cloud Storage 中创建新的 csv 文件 的相关文章

  • 从 Firestore 获取文档时,我是否也获取该文档内的集合?

    如果是的话 如何获得它 因为在进行文档引用时 您只能访问该文档的字段 而不能访问集合 从 Firestore 获取文档时 我是否也得到了 该文档内的集合 不 当获取文档时 您只会获取该文档的字段 正如本节中所解释的document http
  • 如何在 Ubuntu 上安装 Python 模块

    我刚刚用Python写了一个函数 然后 我想将其做成模块并安装在我的 Ubuntu 11 04 上 这就是我所做的 创建 setup py 和 function py 文件 使用 Python2 7 setup py sdist 构建分发文
  • 如何更改充当按钮的范围的文本

    我正在为自定义 Web 应用程序编写自动化测试 我遇到了无法更改跨度文本的问题 我尝试过使用 driver execute script 但没有运气 如果我更好地了解 javascript 这确实会有帮助 据我所知 您无法单击跨度 并且列表
  • Dask DataFrame 的逐行处理

    我需要处理一个大文件并更改一些值 我想做这样的事情 for index row in dataFrame iterrows foo doSomeStuffWith row lol doOtherStuffWith row dataFrame
  • 获取单个方程的脚本

    在文本文件中输入 a 2 8 b 3 9 c 4 8 d 5 9 e a b f c d g 0 6 h 1 7 i e g j f h output i j 期望的输出 输出 2 8 3 9 0 6 4 8 5 9 1 7 如果输入文件名
  • Python 中 genfromtxt() 的可变列数?

    我有一个 txt具有不同长度的行的文件 每一行都是代表一条轨迹的一系列点 由于每条轨迹都有自己的长度 因此各行的长度都不同 也就是说 列数从一行到另一行不同 据我所知 genfromtxt Python 中的模块要求列数相同 gt gt g
  • Sorted(key=lambda: ...) 背后的语法[重复]

    这个问题在这里已经有答案了 我不太明白背后的语法sorted 争论 key lambda variable variable 0 Isn t lambda随意的 为什么是variable在看起来像的内容中陈述了两次dict 我认为这里的所有
  • 使用 genfromtxt 导入 numpy 中缺失值的 csv 数据

    我有一个 csv 文件 看起来像这样 实际文件有更多的列和行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 假设文件的名称是info csv如果我尝试使用导入它 data numpy genfromtxt i
  • 使用Python将图像转换为十六进制格式

    我的下面有一个jpg文件tmp folder upload path tmp resized test jpg 我一直在使用下面的代码 Method 1 with open upload path rb as image file enco
  • Python 中的这种赋值方式叫什么? a = b = 真

    我知道关于元组拆包 http docs python org tutorial datastructures html tuples and sequences但是当一行中有多个等号时 这个赋值被称为什么 阿拉a b True 它总是让我有
  • 从 Android 访问云存储

    我一直无法找到任何有关如何从 Android 应用程序使用云存储的具体文档 我确实遇到过这个客户端库 https cloud google com storage docs reference libraries然而 Google Clou
  • 在 Mac 上安装 Pygame 到 Enthought 构建中

    关于在 Mac 上安装 Pygame 有许多未解答的问题 但我将在这里提出我的具体问题并希望得到答案 我在 Mac 上安装 Pygame 时遇到了难以置信的困难 我使用 Enthought 版本 EPD 7 3 2 32 位 它是我的默认框
  • Python int 太大,无法放入 SQLite

    我收到错误 OverflowError Python int 太大 无法转换为 SQLite INTEGER 来自以下代码块 该文件约25GB 因此必须分部分读取 length 6128765 Works on partitions of
  • 负整数的Python表示

    gt gt gt x 4 gt gt gt print b format x x 4 100 gt gt gt mask 0xFFFFFFFF gt gt gt print b format x mask x mask 4294967292
  • 如何逐像素绘制正方形(Python,PIL)

    在空白画布上 我想使用 Pillow 逐像素绘制一个正方形 我尝试使用 img putpixel 30 60 155 155 55 绘制一个像素 但它没有执行任何操作 from PIL import Image def newImg img
  • 是否可以写一个负的python类型注释

    这可能听起来不合理 但现在我需要否定类型注释 我的意思是这样的 an int Not Iterable a string Iterable 这是因为我为一个函数编写了一个重载 而 mypy 不理解我 我的功能看起来像这样 overload
  • 是否可以强制浮点数的指数或有效数匹配另一个浮点数(Python)?

    这是我前几天试图解决的一个有趣的问题 是否可以强制一个的有效数或指数float与另一个人一样float在Python中 出现这个问题是因为我试图重新调整一些数据 以便最小值和最大值与另一个数据集匹配 然而 我重新调整后的数据略有偏差 大约小
  • asyncio - 多次等待协程(周期性任务)

    我正在尝试为异步事件循环创建定期任务 如下所示 但是我收到 RuntimeError 无法重用已等待的协程 异常 显然 asyncio 不允许等待相同的可等待函数 如中讨论的这个错误线程 https bugs python org issu
  • 如何识别图形线条

    我有以下格式的路径的 x y 数据 示例仅用于说明 seq p1 p2 0 20 2 3 1 20 2 4 2 20 4 4 3 22 5 5 4 22 5 6 5 23 6 2 6 23 6 3 7 23 6 4 每条路径都有多个点 它们
  • 使用 numpy 加速 for 循环

    下一个 for 循环如何使用 numpy 获得加速 我想这里可以使用一些奇特的索引技巧 但我不知道是哪一个 这里可以使用 einsum 吗 a 0 for i in range len b a numpy mean C d e f b i

随机推荐