能否通过BigQuery UDF读取GCS对象元数据完成数据入湖校验?
GCS到BigQuery导入行数校验方案
优先推荐轻量方案(无需编写JS)
你完全不需要使用JS UDF就能实现需求,操作步骤更简单:
- 第一步:提取GCS文件元数据中的行数值,直接用gcloud命令即可获取:
gcloud storage objects describe gs://<你的桶路径>/<目标文件名> --format="value(metadata.<你自定义的行数字段名>)"
你可以把返回的数值存到脚本变量,或者写入BigQuery临时表待用 - 第二步:统计BigQuery导入后目标表的实际行数,执行SQL:
SELECT COUNT(*) AS bq_row_count FROM<你的项目>.<你的数据集>.<目标表名>`` - 第三步:直接对比两个数值是否一致即可,整套逻辑可以嵌入到你的导入调度流程(比如Cloud Function、Dataflow、Airflow)里自动执行,全程不需要写JS代码。
若需全流程在BigQuery内执行的JS UDF方案
如果你需要所有校验逻辑都在BigQuery内完成,可按以下步骤操作,不需要你自己写JS逻辑,直接复用现成打包好的依赖即可:
- 下载已经编译打包好的兼容浏览器端的
@google-cloud/storage库min.js文件,确保所有依赖都已经打包到单文件内,没有Node.js专属API依赖 - 将该js文件上传到你有权限的GCS桶中,比如存储路径为
gs://<你的工具桶>/js/gcs-storage.min.js - 执行以下SQL创建自定义UDF:
CREATE OR REPLACE FUNCTION <你的数据集>.get_gcs_metadata_rowcount(gcs_file_full_path STRING, rowcount_metadata_key STRING) RETURNS INT64 LANGUAGE js AS ''' const {Storage} = require('@google-cloud/storage'); const storage = new Storage(); const pathSeg = gcs_file_full_path.replace('gs://','').split('/'); const bucket = pathSeg[0]; const filePath = pathSeg.slice(1).join('/'); const [metadata] = await storage.bucket(bucket).file(filePath).getMetadata(); return parseInt(metadata.metadata[rowcount_metadata_key],10); ''' OPTIONS ( library="gs://<你的工具桶>/js/gcs-storage.min.js" );
- 注意:你需要提前给BigQuery服务账号授予该GCS工具桶和存储导入文件桶的对象读取权限,否则UDF会报错。
- 执行以下SQL即可直接完成行数对比校验:
WITH params AS ( SELECT 'gs://<你的业务桶>/<导入的文件名>' AS gcs_file_path, 'row_count' AS rowcount_meta_key, -- 替换成你自己定义的元数据行数字段名 `<你的项目>.<你的数据集>.<目标表名>` AS bq_table ), expected_count AS ( SELECT <你的数据集>.get_gcs_metadata_rowcount(gcs_file_path, rowcount_meta_key) AS count FROM params ), actual_count AS ( SELECT COUNT(*) AS count FROM params, UNNEST([bq_table]) AS table_ref ) SELECT e.count AS expected_row_count, a.count AS actual_bq_row_count, e.count = a.count AS is_row_count_match FROM expected_count e, actual_count a
内容的提问来源于stack exchange,提问作者KISHAN DHRANGADHARIYA
相关产品推荐
相关产品推荐

