当前位置: 首页 > 知识库问答 >
问题:

使用间接模式更改更新BigQuery视图

商皓
2023-03-14

更新视图时,间接模式更改似乎不会被拾取。

  • 使用字段字段 1 创建视图 1(例如,选择 1 AS 字段 1
  • 创建视图 2,从视图 1 中选择所有字段
  • 更新视图 1 以包括字段 2(例如,选择 1 AS 字段 1,2 AS 字段 2
  • 使用与以前相同的查询更新 view2(由于记录的限制)
  • 视图1视图2,包括字段1字段2的架构
  • 视图更新应该是原子的
    < li >正确更新了< code >视图1的模式(包括< code >字段1和< code >字段2) < Li > < code > view 2 的模式仅包括< code>field1 < li >从< code>view2中进行选择实际上会返回< code>field1和< code>field2

我可以删除view2并再次重新创建它,但这不会是原子的,并且会有一段时间视图不可用,这是不需要的。

我还尝试更新<code>view2:

Google . API _ core . exceptions . bad request:400 PATCH/datasets/dataset 1/tables/view 2 " rel = " no follow no referrer " > https://www . Google API . com/big query/v2/projects/

是否有任何方法可以自动更新视图,同时也更新间接更改的架构(视图从中选择的表/视图)。

注意:当然,我的view2会添加其他字段,目前我可以通过创建一个新的临时视图来确定其模式。

注意:模式很重要,因为Data Studio的BigQuery连接器等工具正在检查模式。

# Python 3.6+
import google.api_core.exceptions
from google.cloud import bigquery


def delete_table_if_exists(client: bigquery.Client, table: bigquery.Table):
    try:
        client.delete_table(table)
    except google.api_core.exceptions.NotFound:
        pass


def full_table_id(table: bigquery.Table) -> str:
    # Note: the documentation says it should be separated by a dot but uses a colon
    return table.full_table_id.replace(':', '.')


def view_test():
    client = bigquery.Client()

    dataset_ref = client.dataset('dataset1')
    try:
        client.create_dataset(dataset_ref)
    except google.api_core.exceptions.Conflict:
        pass

    view1 = bigquery.Table(dataset_ref.table('view1'))
    view2 = bigquery.Table(dataset_ref.table('view2'))
    delete_table_if_exists(client, view1)
    delete_table_if_exists(client, view2)

    view1.view_query = 'SELECT 1 AS field1'
    view1 = client.create_table(view1)

    view2.view_query = f'SELECT * FROM `{full_table_id(view1)}`'
    client.create_table(view2)

    view1.view_query = 'SELECT 1 AS field1, 2 AS field2'
    client.update_table(view1, ['view_query'])

    client.update_table(view2, ['view_query'])
    print('view2 schema:', client.get_table(view2).schema)

    # trying to update the schema fails with 'Cannot add fields (field: field2)'
    view2.schema = client.get_table(view1).schema
    client.update_table(view2, ['schema'])


if __name__ == '__main__':
    view_test()
#!/bin/bash

set -e

project_id=$(gcloud config list --format 'value(core.project)' 2>/dev/null)

bq mk -f dataset1

bq rm -f dataset1.view1
bq rm -f dataset1.view2

bq mk --use_legacy_sql=false --view 'SELECT 1 AS field1' dataset1.view1
bq mk --use_legacy_sql=false --view 'SELECT * FROM `'$project_id'.dataset1.view1`' dataset1.view2

bq update --use_legacy_sql=false --view 'SELECT 1 AS field1, 2 AS field2' dataset1.view1
bq update --use_legacy_sql=false --view 'SELECT * FROM `'$project_id'.dataset1.view1`' dataset1.view2

bq show dataset1.view2
def get_create_or_replace_view_query(view: bigquery.Table) -> str:
    return f'CREATE OR REPLACE VIEW {view.dataset_id}.{view.table_id} AS {view.view_query}'


def view_test():
    # ...
    query_job = client.query(get_create_or_replace_view_query(view2))
    query_job.result()
    print('view2 schema:', client.get_table(view2).schema)
bq query --use_legacy_sql=false 'CREATE OR REPLACE VIEW dataset1.view2 AS SELECT * FROM `'$project_id'.dataset1.view1`'

共有1个答案

林俊英
2023-03-14

您应该使用< code>CREATE OR REPLACE VIEW语句;请参见相关文档。BigQuery为所有执行表修改的查询提供了ACID语义,而< code>CREATE OR REPLACE VIEW也不例外,因此这将自动替换视图的定义和模式。

 类似资料:
  • 问题内容: 我试图弄清楚Angular的工作原理,并在模型更改时无法更新视图。 的HTML JS http://jsfiddle.net/N2G7z/ 有任何想法吗? 问题答案: 正如上面提到的Ajay beniwal一样,您需要使用Apply来开始消化。

  • 我们正在BigQuery表上进行流式插入。 我们希望在不更改表名的情况下更新表的模式。 例如,我们希望删除一列,因为它包含敏感数据,但是我们希望保持所有其他数据和表名不变。 我们的流程如下: 将原始表复制到临时表 删除原始表 使用原始表名和新架构创建新表。 用旧表的数据填充新表。 哭,因为最后(最多)90分钟的数据卡在流缓冲区中,未传输 如何避免最后一步?

  • 我们的 BigQuery 模式是大量嵌套/重复的,并且不断变化。例如,网站的新页面、表单或用户信息字段将与 BigQuery 中的新列相对应。此外,如果我们停止使用某种形式,相应的弃用列将永远存在,因为您无法删除Bigquery中的列。 因此,我们最终将生成包含数百列的表,其中许多列已被弃用,这似乎不是一个好的解决方案。 我正在研究的主要替代方案是将所有内容都存储为json(例如,每个Bigque

  • 问题内容: 我目前正在使用基于Web的Twitter客户端,因此我使用了angular.js,node.js和socket.io。我通过socket.io将新的推文推到我的客户端,服务在其中等待新的推文。当一条新的推文到来时,该服务通过$ broadcast发送事件。 在我的控制器中是一个事件侦听器,其中传入的tweet在单独的函数中进行处理。此功能只是将新的推文推入我的推文范围。 现在,我的问题

  • 问题内容: 我目前正在尝试弄清楚如何在不重新加载整个页面的情况下更改路由参数。例如,如果我从 http://www.example.com/#/page 但将名称更新为“乔治”,将路线更改为: http://www.example.com/#/page/george 如果我已经路由了http://www.example.com/#/page/:name。 无需重新加载位置。可以只设置$ route

  • 问题内容: 我已经阅读了有关此问题的主题,例如:[\AngularJS中未更新视图,\但我仍然不明白如何在我的简单示例中应用它。 我有这个功能: 当代码中的其他地方更新时(用户单击,交互,发送XHR请求时),它不会更新我的视图。我知道我需要使用$apply做些事情,但我不知道在哪里以及如何做。 有人可以向我解释如何针对这个简单用例解决此问题吗? 我的模型看起来像这样(如果这个问题是必要的)-它里面