为什么加载BigQuery表需要存储桶?

时间:2019-06-26 07:24:50

标签: scala apache-spark google-cloud-platform google-bigquery

我正在尝试使用Spark,Scala将BigQuery表加载到程序中,但是我无法理解BigQuery在BigQuery中的作用。

我遵循https://github.com/samelamin/spark-bigqueryhttps://cloud.google.com/dataproc/docs/tutorials/bigquery-connector-spark-example上的示例,因为我将projectId更改为自己的ID,并下载了用于身份验证的服务帐户.json文件。

这是我的代码

import com.samelamin.spark.bigquery._

class SparkSessionFunctions(val spark: SparkSession) {
def loadBQTable[T]: Unit = {
    val sqlContext = spark.sqlContext
    sqlContext.setBigQueryGcsBucket("bucketname") // What's this for?
    sqlContext.setBigQueryProjectId("data-staging-5c4d")
    sqlContext.setGcpJsonKeyFile("/key.json")
    sqlContext.hadoopConf.set("fs.gs.project.id","data-staging-5c4d")

    val df = spark.sqlContext.read.format("com.samelamin.spark.bigquery").option("tableReferenceSource","data-staging-5c4d:data_warehouse.table_to_load").load()
    println("df: " + df.select("id").collect())
    df
  }
}

运行命令prinitln(df)可以显示我的表模式,但是由于错误提示我的服务帐户does not have storage.objects.get access to bucket bucketname/hadoop/tmp/bigquery/job_20190626140444_0000.

,我无法从表本身收集任何信息

据我了解,存储桶仅在GCS中使用,而在BigQuery中根本没有使用。那么为什么两个库都需要指定存储桶值才能使其正常工作?

1 个答案:

答案 0 :(得分:2)

在这种情况下,存储桶与BigQuery(与Google Cloud Storage)无关。实际上,Spark连接器首先将数据作为过渡区域传输到GCS(因此需要使用存储桶),然后然后传输到BigQuery。

许多连接器都以这种方式工作,因为您可以通过BigQuery中的External Data Source直接从Cloud Storage中的CSV查询。这样一来,您就可以将Cloud Storage中的文件视为一个表,并使用BigQuery的计算方式对其进行查询,包括自动检测模式的选项-与使用BigQuery API进行更复杂的集成相比,它往往是一种更快的ELT / ETL数据存储方式。 / p>

要更正导致错误的原因,您需要在IAM&Admin(很可能是Storage Object Viewer)下的控制台中为服务帐户分配适当的权限角色。

更新:您可能还需要检查存储桶以及对象(文件)本身的权限,因为这些权限可以覆盖默认的IAM角色权限。您可以从Cloud Storage浏览器顶部存储区的权限选项卡中,以及单个文件旁边的烤肉(三个点)菜单中,然后选择“编辑权限”选项,来执行此操作。请注意,这些对象级权限实际上不是IAM的一部分,而是Access Control Lists(ACL)的一部分,因此一开始它们可能会有些混乱。

我之前错过的另一件事-您所包含的错误消息通常仅包含存储桶名称,但具有完整路径。我将确保对position: absolute的调用仅包含加引号的存储桶名称​​不,包括文件路径。

一旦克服了文件上的权限问题,您可能需要向sqlContext.setBigQueryGcsBucket()添加呼叫,其中区域代码是this list中正确的亚太地区(注意:亚太地区是有点不同;大多数工具使用“ US”或“ EU”的多区域字符串,但也将接受更长的单区域名称。