我们每周都有一个备份流程,将我们的生产Google Appengine数据存储区导出到Google云端存储,然后导入Google BigQuery。每周,我们都会创建一个名为YYYY_MM_DD
的新数据集,其中包含当天生产表的副本。随着时间的推移,我们收集了许多数据集,例如2014_05_10
,2014_05_17
等。我想创建一个数据集Latest_Production_Data
,其中包含最近的每个表的视图{ {1}}数据集。这将使下游报告更容易编写一次查询并始终检索最新数据。
为此,我有一些代码可以获取最新的数据集以及数据集包含在BigQuery API中的所有表的名称。然后,对于这些表中的每一个,我触发tables.insert调用以从我想要创建引用的表中创建一个YYYY_MM_DD
的视图。
对于包含SELECT *
字段的表,这看起来是一个非常良性的列命名规则。
例如,我有这张表:
我为此发出了这个API调用:
RECORD
这会导致以下错误:
HttpError:https://www.googleapis.com/bigquery/v2/projects//datasets/Latest_Production_Data/tables?alt=json返回“无效字段名称”__key __。namespace“。字段必须只包含字母,数字,和下划线,以字母或下划线开头,最多128个字符。“>
当我在BigQuery Web控制台中执行此查询时,会重命名列以将{
'tableReference': {
'projectId': 'redacted',
'tableId': u'AccountDeletionRequest',
'datasetId': 'Latest_Production_Data'
}
'view': {
'query': u'SELECT * FROM [2014_05_17.AccountDeletionRequest]'
},
}
转换为.
。我发布创建视图API调用时会发生同样的事情。
有没有一种简单的方法可以编程方式为我的数据集中的每个表创建一个视图,而不管它们的底层模式如何?我现在遇到的问题是记录列,但我预期的另一个问题是具有重复字段的表。 _
是否有一些神奇的选择可以解决所有这些错综复杂的问题?
我的另一个想法是做table copy,但如果我可以完全避免,我宁愿不复制数据。
答案 0 :(得分:1)
我们遇到了一个错误,您需要在视图中选择单个字段并使用' as'将字段重命名为合法的字段(即名称中没有'。')。
该错误现已修复,因此您不应再看到此问题。如果再次看到,请ping这个帖子或开始一个新问题。
答案 1 :(得分:1)
这是我写的workaround code为每个表动态生成SELECT
语句:
def get_leaf_column_selectors(dataset, table):
schema = table_service.get(
projectId=BQ_PROJECT_ID,
datasetId=dataset,
tableId=table
).execute()['schema']
return ",\n".join([
_get_leaf_selectors("", top_field)
for top_field in schema["fields"]
])
def _get_leaf_selectors(prefix, field):
if prefix:
format = prefix + ".%s"
else:
format = "%s"
if 'fields' not in field:
# Base case
actual_name = format % field["name"]
safe_name = actual_name.replace(".", "_")
return "%s as %s" % (actual_name, safe_name)
else:
# Recursive case
return ",\n".join([
_get_leaf_selectors(format % field["name"], sub_field)
for sub_field in field["fields"]
])