从 GCP BigQuery 导出到 parquet:如何获得正确的数字类型的比例、精度?

问题描述 投票:0回答:1

我在 BQ 的表 A 中有一个类型为 NUMERIC(29) 的列 A。我使用 BigQueryToGCSOperator 将其导出到镶木地板:

transferBigQuerryToBucket = BigQueryToGCSOperator(
    task_id='BigQuerryToBucket'
        ,source_project_dataset_table= xyz
        ,compression="GZIP"
        ,destination_cloud_storage_uris=xyz
        ,location=xyz
        ,export_format="Parquet"
        ,force_rerun=True)

并用 pyspark 读入它。

我遇到了一个问题,因为 Spark 将该表视为

StructType([StructField('columnA', DecimalType(38,9), True])

我认为可能是气流算子或者spark的问题,所以我直接从BQ导出数据:

EXPORT DATA OPTIONS(
  format='PARQUET',
  uri='gs://address',
  overwrite=true
)
AS
SELECT columnA
FROM tableA

,然后用 python、pyarrow 读入它 - 所以这里没有气流,没有火花。我得到了:

optional fixed_len_byte_array(16) field_id=-1 columnA (Decimal(precision=38, scale=9));

这会导致问题,因为我在 Spark 数据框中收到类似 213123123132.00000000 的数字,结果我在 csv 中得到这些零。

我看到两种可能的解决方案:

  1. 为表提供单独的模式 - 但这会给我的工作流程增加很多工作,我希望避免它,因为镶木地板应该在元数据中保存模式。
  2. 某种 Spark 函数/UDF 将删除那些 0 (虽然我需要一个通用的解决方案,而不是特定于 tableA),但我在这里看到很多问题 - 条件是什么,即要修改哪些记录,要使用哪个函数等等。更不用说这种方法的效率了。

这些解决方案都没有直接解决问题 - 元数据中的信息错误(或者可能是 python/pyspark 读取此元数据时出现问题)。

如有任何建议,我将不胜感激。谢谢你

apache-spark pyspark google-bigquery parquet pyarrow
1个回答
0
投票

不幸的是,这是查询中参数化类型的限制。来自文档:

A data type's parameters are not propagated in an expression, only the data type is.


在这种情况下,如果您想保留 Spark 中的类型,您可以尝试使用

BigQuerySparkConnector 直接传输数据,这有助于保留参数化。我对气流了解不够,不知道如何在该环境中进行设置。

© www.soinside.com 2019 - 2024. All rights reserved.