【发布时间】:2019-05-31 21:56:38
【问题描述】:
在 Google 的大查询中,有没有办法克隆(单独复制结构)没有数据的表?
bq cp 似乎没有复制没有数据的结构的选项。 并且使用诸如“1 = 2”之类的过滤器将表创建为选择(CTAS)确实会创建没有数据的表。但是,它不会复制分区/集群属性。
【问题讨论】:
-
请查看thread中给出的建议
标签: google-bigquery
在 Google 的大查询中,有没有办法克隆(单独复制结构)没有数据的表?
bq cp 似乎没有复制没有数据的结构的选项。 并且使用诸如“1 = 2”之类的过滤器将表创建为选择(CTAS)确实会创建没有数据的表。但是,它不会复制分区/集群属性。
【问题讨论】:
标签: google-bigquery
您可以按照您的建议使用 BigQuery API 运行选择,这将返回空结果并设置分区和集群字段。
这是一个示例(仅分区但集群也可以)
curl --request POST \
'https://www.googleapis.com/bigquery/v2/projects/myProject/jobs' \
--header 'Authorization: Bearer [YOUR_BEARER_TOKEN]' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{"configuration":{"query":{"query":"SELECT * FROM `Project.dataset.audit` WHERE 1 = 2","timePartitioning":{"type":"DAY"},"destinationTable":{"datasetId":"datasetId","projectId":"projectId","tableId":"test"},"useLegacySql":false}}}' \
--compressed
【讨论】:
你可以使用DDL和limit 0,但你也需要在查询中表达分区和聚类
#standardSQL
CREATE TABLE mydataset.myclusteredtable
PARTITION BY DATE(timestamp)
CLUSTER BY
customer_id
AS SELECT * FROM mydataset.myothertable LIMIT 0
【讨论】:
如果您想克隆表的结构以及分区/集群属性而无需知道这些分区/集群属性的确切含义 - 请按照以下步骤操作:
第 1 步:只需将 your_table 复制到新表 - 比如说 your_table_copy。这显然会复制整个表,包括所有属性(包括描述、分区到期等 - 如果您尝试手动设置它们很容易错过)和数据。注意:复制是免费操作
第 2 步:删除新创建的表中的数据 - 运行以下查询语句
SELECT * FROM `project.dataset.your_table_copy` LIMIT 0
在上面运行时,请确保将 project.dataset.your_table_copy 设置为目标表,并将“覆盖表”设置为“写入首选项”。注意:这也是免费步骤(因为 LIMIT 0)
您可以在 Web UI、命令行或 API 或您选择的任何客户端中轻松完成上述两个步骤 - 无论您最喜欢什么
【讨论】:
最后,我使用下面的 python 脚本来检测架构/分区/集群属性以重新创建(克隆)没有数据的集群表。我希望我们从 bigquery 中获得一个开箱即用的功能来克隆表结构,而无需像这样的脚本。
import commands
import json
BQ_EXPORT_SCHEMA = "bq show --schema --format=prettyjson %project%:%dataset%.%table% > %path_to_schema%"
BQ_SHOW_TABLE_DEF="bq show --format=prettyjson %project%:%dataset%.%table%"
BQ_MK_TABLE = "bq mk --table --time_partitioning_type=%partition_type% %optional_time_partition_field% --clustering_fields %clustering_fields% %project%:%dataset%.%table% ./%cluster_json_file%"
def create_table_with_cluster(bq_project, bq_dataset, source_table, target_table):
cmd = BQ_EXPORT_SCHEMA.replace('%project%', bq_project)\
.replace('%dataset%', bq_dataset)\
.replace('%table%', source_table)\
.replace('%path_to_schema%', source_table)
commands.getstatusoutput(cmd)
cmd = BQ_SHOW_TABLE_DEF.replace('%project%', bq_project)\
.replace('%dataset%', bq_dataset)\
.replace('%table%', source_table)
(return_value, output) = commands.getstatusoutput(cmd)
bq_result = json.loads(output)
clustering_fields = bq_result["clustering"]["fields"]
time_partitioning = bq_result["timePartitioning"]
time_partitioning_type = time_partitioning["type"]
time_partitioning_field = ""
if "field" in time_partitioning:
time_partitioning_field = "--time_partitioning_field " + time_partitioning["field"]
clustering_fields_list = ",".join(str(x) for x in clustering_fields)
cmd = BQ_MK_TABLE.replace('%project%', bq_project)\
.replace('%dataset%', bq_dataset)\
.replace('%table%', target_table)\
.replace('%cluster_json_file%', source_table)\
.replace('%clustering_fields%', clustering_fields_list)\
.replace('%partition_type%', time_partitioning_type)\
.replace('%optional_time_partition_field%', time_partitioning_field)
commands.getstatusoutput(cmd)
create_table_with_cluster('test_project', 'test_dataset', 'source_table', 'target_table')
【讨论】:
这可以通过 BQ CLI 实现。
先下载已有表的schema:
bq show --format=prettyjson project:dataset.table | jq '.schema.fields' > table.json
然后,使用提供的架构和所需的分区创建一个新表:
bq mk \
--time_partitioning_type=DAY \
--time_partitioning_field date_field \
--require_partition_filter \
--table dataset.tablename \
table.json
查看更多关于bq mk选项的信息:https://cloud.google.com/bigquery/docs/tables
安装jq 与:npm install node-jq
【讨论】:
BigQuery 现在为此明确支持 CREATE TABLE LIKE。
请参阅下面链接的文档:
【讨论】: