我正在尝试使用Spark,Scala将BigQuery表加载到程序中,但是我无法理解BigQuery在BigQuery中的作用。
我遵循https://github.com/samelamin/spark-bigquery和https://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中根本没有使用。那么为什么两个库都需要指定存储桶值才能使其正常工作?
答案 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”的多区域字符串,但也将接受更长的单区域名称。