我正在将BigQuery中的表格读入Spark。该表具有以下列:id(int),string1(string),string2(string),string3(string),date(date)和timestamp(int)。现在,我想根据其ID将结果数据帧的行写入BigQuery中的单独表。例如,有700个ID为1的行,我想创建一个表project.dataset.id1,并将所有这700行(所有列)写入该表,然后所有ID为2的行都应进入一个表project.dataset.id2,依此类推。
如果我正在写文本文件,我将使用write.partitionBy('id'),那么在写入BigQuery时该怎么办?
我试图使用python解决它,但是它非常慢,我想知道是否有更好的方法来实现它。
这是我到目前为止尝试过的:
#!/usr/bin/python
from pyspark.sql import SparkSession
from pyspark import SparkContext
from pyspark import SparkConf
from pyspark.sql import SQLContext
from google.cloud import bigquery
sc = SparkContext().getOrCreate()
sc.setLogLevel("ERROR")
spark = SparkSession\
.builder\
.appName("example-spark")\
.getOrCreate()
df = spark.read.format('bigquery').option('table', 'project.dataset.input_table').load()
ids = df.select("id").distinct().rdd.flatMap(lambda x: x).collect()
dfs = [df.where(df["id"] == id) for id in ids]
client = bigquery.Client()
dataset_ref = client.dataset('test2')
for df in dfs:
id = str(df.select("id").distinct().rdd.flatMap(lambda x: x).collect()[0])
table_name = "source_table_%s" % (id)
table_ref = dataset_ref.table(table_name)
schema = [
bigquery.SchemaField('source_id', 'INT64', mode='REQUIRED'),
bigquery.SchemaField('string1', 'STRING', mode='NULLABLE'),
bigquery.SchemaField('string2', 'STRING', mode='NULLABLE'),
bigquery.SchemaField('string3', 'STRING', mode='NULLABLE'),
bigquery.SchemaField('date', 'DATE', mode='NULLABLE'),
bigquery.SchemaField('timestamp', 'INT64', mode='NULLABLE')
]
table = bigquery.Table(table_ref, schema=schema)
table = client.create_table(table)
print('table {} created.'.format(table.table_id))
table_path = "project.dataset.%s" % (table_name)
df.write.format('bigquery').option('table', table_path).mode("overwrite").save()
我正在考虑按id进行分组/分区,然后使用针对BigQuery的python API,然后使用.write.format('bigquery')将行写入该表,以便按其ID命名的组创建一个新表。
我可以使用什么函数按ID将数据框“分成”几部分,然后遍历每个部分以创建表并执行写操作?
此外,应用该函数后我将使用哪种数据类型(如何访问用于命名表的id)?
答案 0 :(得分:0)
抱歉,这不能直接回答问题,但是我想提出一种不同的方法。您可以创建一个由id列分区的单个表,而不必在BigQuery中创建和管理多个表。
详细了解整数分区: https://cloud.google.com/bigquery/docs/creating-integer-range-partitions
设置完毕后,您只需写入该表,BigQuery便会为您进行分区。当您阅读时,使用过滤器FROM Table WHERE id = 12345
进行的阅读将代替阅读FROM TableId12345
。通常,这更易于管理且更易于实现。