从大型 pandas 数据帧加载 BigQuery 表

Loading BigQuery tables from large pandas DataFrames

我正在尝试使用官方 python 将相对较大的 pandas 数据帧 df 加载到 Google BigQuery table table_ref google-cloud-bigquery 客户端库。

到目前为止,我尝试了两种不同的方法:

1) 直接从内存中的数据帧加载table

client = bigquery.Client()
client.load_table_from_dataframe(df, table_ref)

2) 将数据帧保存到 Google Cloud Storage 中的镶木地板文件中 parquet_uri 并从该文件加载 table:

df.to_parquet(parquet_uri)
client = bigquery.Client()
client.load_table_from_uri(parquet_uri, table_ref)

两种方法都会导致相同的错误:

google.api_core.exceptions.BadRequest: 400 Resources exceeded during query execution: UDF out of memory.; Failed to read Parquet file [...]. This might happen if the file contains a row that is too large, or if the total size of the pages loaded for the queried columns is too large.

数据框 df 有 3 列和 1.84 亿行。保存为parquet文件格式时,占用1.64GB。

有没有什么方法可以使用官方 python 客户端库将这样的数据帧上传到 BigQuery table?

提前谢谢你,

乔瓦尼

如果您的 parquet 文件已经加载到 Google Cloud Storage,您可以直接加载到 BigQuery,无需 python 脚本:

bq load \
--source_format=PARQUET \
dataset.table \
"gs://mybucket/00/*.parquet","gs://mybucket/01/*.parquet"

其中:

  • mybucket 是您加载 parquet 文件的桶。
  • dataset.table 是你的 table

通过这种方式,BigQuery 会自动检测架构。

BigQuery 支持 Parquet 文件中数据块的以下压缩编解码器:

  • 活泼的 GZip
  • LZO_1C
  • LZO_1X

您可以在此处阅读更多内容 link:https://cloud.google.com/bigquery/docs/loading-data-cloud-storage-parquet

我能够将大 df 上传到 BigQuery,方法是将它分成几个块并将它们中的每一个加载到 BigQuery 中的 table,例如:

client = bigquery.Client()
for df_chunk in np.array_split(df, 5):
    job_config = bigquery.LoadJobConfig()
    job_config.write_disposition = bigquery.WriteDisposition.WRITE_APPEND
    job = client.load_table_from_dataframe(df_chunk, table_id, job_config=job_config)
    job.result()

Parquet是列式数据格式,也就是说加载数据需要读取所有列。在 parquet 中,列被分成页面。 BigQuery 在从中读取数据时将每一列的整个未压缩页面保存在内存中。如果输入文件包含太多列,BigQuery worker 可能会遇到内存不足错误。 如果您考虑增加查询的分配内存,则需要阅读 Bigquery 插槽。