[英]BigQuery insert values AS, assume nulls for missing columns
假设有一个包含 1000 列的表。 我想添加一行包含 20 列的值,并假设NULL
为 NULL。
INSERT VALUES
语法可用于此:
INSERT INTO `tbl` (
date,
p,
... # 18 more names
)
VALUES(
DATE('2020-02-01'),
'p3',
... # 18 more values
)
它的问题是很难分辨哪个值对应于哪个列。 如果您需要更改/注释掉某些值,则必须在两个地方进行编辑。
也可以使用INSERT SELECT
语法:
INSERT INTO `tbl`
SELECT
DATE('2020-02-01') AS date,
'p3' AS p,
... # 18 more value AS column
... # 980 more NULL AS column
然后,如果我需要注释掉某些列,则只需注释掉一行。 但显然必须设置 980 NULL
s 是很不方便的。
结合这两种方法的方法是什么? 实现类似的目标:
INSERT INTO `tbl`
SELECT
DATE('2020-02-01') AS date,
'p3' AS p,
... # 18 more value AS column
上面的查询不起作用,错误是Inserted row has wrong column count; Has 20, expected 1000
Inserted row has wrong column count; Has 20, expected 1000
。
您的第一个版本确实是您唯一应该用于 SQL 插件的版本。 它确保每个目标列都被明确提及,并且对于VALUES
子句中的文字应该 go 的位置是明确的。 您可以使用未明确提及列名的版本。 起初,您似乎在为自己节省一些代码。 但是要意识到有一个列列表将被使用,它是所有表列的列表,无论它们在定义中的位置是什么。 您的代码可能会起作用,但请注意,任何添加/删除列或更改列顺序都可能完全破坏您的插入脚本。 出于这个原因,大多数人会强烈主张第一个版本。
您可以尝试以下解决方案,它是您在案例研究中突出显示的上述 2 个过程的组合:-
INSERT INTO `tbl` (date, p, 18 other coll names)
SELECT
DATE('2020-02-01') AS date,
'p3' AS p,
... # 18 more value AS column
您应该在这里考虑的几件事是:-
希望它对你有用。
在 BigQuery 中,执行您所描述的操作的最佳方法是首先加载到暂存表。 我假设您可以使用与目标列名称相对应的键获取要插入到 JSON 格式中的值。
values.json
{"date": "2020-01-01", "p": "p3", "column": "value", ... }
然后为目标表生成schema文件并保存到本地
bq show --schema project:dataset.tbl > schema.json
使用目标架构将新数据加载到暂存表。 这会为目标模式中存在但在 json 中缺失的每一列“命名” null 值,绕过将它们写出的需要。
bq load --replace --source_format=NEWLINE_DELIMIITED_JSON \
project:dataset.stg_tbl values.json schema.json
现在 insert select 语句每次都有效
insert into `project:dataset.tbl`
select * from `project:dataset.stg_tbl`
不是一个纯粹的 SQL 解决方案,但我通过用数据加载我的暂存表然后运行类似的东西来管理这个:
from google.cloud import bigquery
client = bigquery.Client()
table1 = client.get_table(f"{project_id}.{dataset_name}.table1")
table1_col_map = {field.name: field for field in table1.schema}
table2 = client.get_table(f"{project_id}.{dataset_name}.table2")
table2_col_map = {field.name: field for field in table2.schema}
combined_schema = {**table2_col_map, **table1_col_map}
table1.schema = list(combined_schema.values())
client.update_table(table1_cols, ["schema"])
解释:
这将检索两者的模式,将它们的模式转换为一个字典,其中键作为列名,值作为 sdk 中的实际字段信息。然后将两者与字典解包结合(解包的顺序决定了当一个表的列优先column are common between them. 最后,组合模式被分配回表 1 并用于更新表,添加带有空值的缺失列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.