Google bigquery 在上传到BigQuery之前取消GCS文件的规范化

Google bigquery 在上传到BigQuery之前取消GCS文件的规范化,google-bigquery,google-cloud-storage,google-cloud-run,Google Bigquery,Google Cloud Storage,Google Cloud Run,我在.NETCore中编写了一个云运行API,它从GCS位置读取文件,然后进行非规范化(即为每行添加更多信息以包含文本描述),然后将其写入BigQuery表。我有两个选择: 我的云运行API可以创建非规范化的CSV文件,并将它们写入另一个GCS位置。然后,另一个云运行API可以提取这些非规范化的CSV文件,并将它们直接写入BigQuery 我的云运行API可以读取原始CSV文件,在内存中对它们进行非规范化(filestream),然后以某种方式从内存中的filestream直接写入BigQuer

我在.NETCore中编写了一个云运行API,它从GCS位置读取文件,然后进行非规范化(即为每行添加更多信息以包含文本描述),然后将其写入BigQuery表。我有两个选择:

  • 我的云运行API可以创建非规范化的CSV文件,并将它们写入另一个GCS位置。然后,另一个云运行API可以提取这些非规范化的CSV文件,并将它们直接写入BigQuery
  • 我的云运行API可以读取原始CSV文件,在内存中对它们进行非规范化(filestream),然后以某种方式从内存中的filestream直接写入BigQuery表
    如果性能(速度)和成本(金钱)是我的目标,那么在这种情况下编写BigQuery的最佳方式是什么。在反规范化之前,这些文件的大小约为10KB。每行大约有1000个字符。在去规范化之后,它大约是原来的三倍。在BigQuery中成功加载非规范化文件后,我不需要保留这些文件。我关心的是性能,以及围绕插入/写入的任何特定BigQuery每日配额。我不认为有任何,除非你是做DML声明,但纠正我,如果我错了

    我会使用在将文件上传到bucket时触发的云函数

    这是如此普遍,谷歌有一个教程,只为这个JSON文件

    然后,我将从以下位置修改示例
    main.py
    文件:

    def流(数据、上下文):
    ''每当文件添加到云存储''时,都会执行此函数'
    bucket_name=数据['bucket']
    文件名=数据['name']
    db\u ref=db.document(u'streaming\u files/%s'%file\u name)
    如果已经摄入了(db\u ref):
    _句柄重复(db\U ref)
    其他:
    尝试:
    _将\插入\ bigquery(bucket\名称、文件\名称)
    _处理成功(db\U ref)
    除例外情况外:
    _句柄错误(db\U ref)
    
    对于接受CSV文件的用户:

    导入json
    导入csv
    导入日志记录
    导入操作系统
    导入回溯
    从日期时间导入日期时间
    从google.api_核心导入重试
    从google.cloud导入bigquery
    从google.cloud导入存储
    进口皮茨
    PROJECT\u ID=os.getenv(“GCP\u项目”)
    BQ_数据集='fromCloudFunction'
    BQ_表='mytable'
    CS=storage.Client()
    BQ=bigquery.Client()
    def流(数据、上下文):
    ''每当文件添加到云存储''时,都会执行此函数'
    bucket_name=数据['bucket']
    文件名=数据['name']
    newRows=后处理(bucket\u name、file\u name)
    #建议您保存
    #由于调试原因,您所处理的内容。
    目的地_bucket=‘后处理’35; gs://后处理/
    目的地名称=文件名称
    #saveRowsToBucket(新行、目的地\u bucket、目的地\u名称)
    rowsInsertIntoBigquery(新行)
    类BigQueryError(异常):
    ''每当发生BigQuery错误时引发异常''
    定义初始化(自我,错误):
    super()。\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    self.errors=错误
    def_格式(自身,错误):
    错误=[]
    对于错误中的错误:
    err.extend(错误['errors'])
    返回json.dumps(err)
    def后处理(存储桶名称、文件名称):
    blob=CS.get\u bucket(bucket\u name).blob(file\u name)
    my_str=blob.download_as_string().decode('utf-8'))
    csv\u reader=csv.DictReader(my\u str.split('\n'))
    新行=[]
    对于csv_读取器中的行:
    修改的_行=行#添加您的逻辑
    newRows.append(已修改的_行)
    返回新行
    def rowsInsertIntoBigquery(行):
    table=BQ.dataset(BQ\u数据集).table(BQ\u表)
    errors=BQ.insert\u rows\u json(表,行)
    如果有错误!=[]:
    引发BigQueryError(错误)
    

    如果需要,仍然需要定义映射(row->newRow)和函数
    saveRowsToBucket

    最重要的是,每天只能将数据加载1000次到BigQuery中。如果有1000多个insert操作,则可能需要了解如何对其进行批处理。(这可以通过将消息推送到PubSub来完成,并使用Cloud Scheduler调用云运行应用程序来清空PubSub主题,然后将它们批量插入BigQuery。)您每分钟有多少个文件?你有实时限制吗?(从文件接收到集成到BigQuery之间的最长持续时间是多少)文件计数只能说是每分钟100-500个文件。无实时限制,但我希望从文件出现在GCS中起15分钟内接收数据。如果我使用此处所示的UploadCSV方法,这是否算作插入操作,并且受每日配额的限制@艾哈迈特-谷歌你到底在用哪种方法?是从文件加载表吗?我在您发送的文档中找不到UploadCSV。无论如何,它可能会创建一个新的应用程序:每天为每个表加载作业-1000(包括失败)每天为每个项目加载作业-100000(包括失败)