Skip to main content
Permite executar consultas SELECT e INSERT em uma tabela no Google BigQuery, incluindo conjuntos de dados públicos. A estrutura da tabela é inferida automaticamente do esquema da tabela do BigQuery. A leitura usa a API REST do BigQuery (tabledata.list); portanto, apenas tabelas nativas podem ser lidas (não é possível ler visões, visões materializadas nem tabelas externas). A gravação usa inserções por streaming (tabledata.insertAll), o que exige que o faturamento esteja habilitado para o projeto.

Sintaxe

Argumentos

Os argumentos project, dataset, table e access_token também podem ser fornecidos no formato key = value; os argumentos posicionais preenchem essas posições nessa ordem, e especificar um argumento tanto por posição quanto como chave (ou repetir a mesma chave) gera um erro. Os seguintes argumentos podem ser especificados no formato key = value (ou como chaves de uma coleção nomeada):

Autenticação

É necessário fornecer exatamente um método de autenticação. O BigQuery não permite acesso anônimo; portanto, as credenciais são necessárias até mesmo para conjuntos de dados públicos.
  1. Token de acesso. Qualquer token de acesso OAuth 2.0 válido, por exemplo, obtido com gcloud auth print-access-token. Os tokens expiram rapidamente (geralmente após uma hora), portanto, esse método é mais adequado para uso interativo.
  2. Chave de conta de serviço (recomendada para servidores). Forneça o conteúdo de um arquivo de chave criado no Google Cloud IAM usando o argumento service_account_key. O ClickHouse assina um JWT com a chave e o troca por um token de acesso, renovando-o automaticamente.
  3. Token de atualização. Forneça client_id, client_secret e refresh_token, por exemplo, extraídos de ~/.config/gcloud/application_default_credentials.json após executar gcloud auth application-default login.
Armazene as credenciais em uma coleção nomeada para evitar especificá-las em cada consulta. Uma tabela permanente criada a partir de uma coleção nomeada (com o motor de tabela BigQuery ou CREATE TABLE ... AS bigquery(...)) é registrada como dependência da coleção. Portanto, DROP NAMED COLLECTION é bloqueado enquanto a tabela existir.

Mapeamento de tipos de dados

Notas:
  • O DATETIME do BigQuery não tem fuso horário; ele é mapeado para DateTime64(6, 'UTC') para que o valor exibido não dependa do fuso horário do servidor.
  • Um RECORD NULLABLE é mapeado para Nullable(Tuple(...)), preservando um NULL de registro completo como NULL, em vez de reduzi-lo a um Tuple de valores padrão. Um array NULL (ou vazio) se torna um array vazio, pois Array não pode estar dentro de Nullable no ClickHouse. Um array do BigQuery não pode conter elementos NULL (ARRAY<T> é equivalente a ARRAY<T NOT NULL>); portanto, o tipo de elemento de um campo REPEATED não é Nullable (Array(T) ou Array(Tuple(...)) para um elemento RECORD). Um elemento NULL em uma resposta tabledata.list é rejeitado como entrada malformada.
  • A leitura e a gravação de colunas Nullable(Tuple(...)) por meio da função de tabela bigquery funcionam sem configurações adicionais. A criação de uma tabela persistente com o mecanismo BigQuery que contenha essa coluna, seja com a estrutura inferida ou declarada explicitamente, requer a configuração enable_nullable_tuple_type, assim como qualquer coluna Nullable(Tuple). Ao declarar colunas explicitamente, um campo RECORD pode ser declarado como um Tuple(...) simples para evitar essa configuração, ao custo de converter um NULL de registro completo em uma tupla padrão; a única diferença aceita em relação ao tipo inferido é remover o Nullable que envolve o Tuple de um RECORD, e somente nesse mesmo registro — a nulabilidade não pode ser movida para outro registro, interno ou externo.
  • GEOGRAPHY é mapeado para Geometry. O BigQuery transfere um valor GEOGRAPHY como texto WKT, que é analisado como a alternativa correspondente de Geometry (um Variant de Point, MultiPoint, Ring, LineString, MultiLineString, Polygon e MultiPolygon) na leitura e serializado novamente como WKT na gravação. Uma GEOMETRYCOLLECTION e uma geometria vazia, como POINT EMPTY, não têm equivalente em Geometry; portanto, a leitura de uma linha que contenha esse valor gera um erro. Como Variant já comporta um NULL, um campo GEOGRAPHY NULLABLE é mapeado para Geometry, e não para Nullable(Geometry), e o NULL continua sendo preservado na ida e volta.
  • JSON é mapeado para String, em vez do tipo de dados JSON, porque o tipo JSON do ClickHouse aceita apenas um objeto ({...}) no nível superior, enquanto um valor JSON do BigQuery pode ser qualquer valor JSON — um escalar, um array ou null. Portanto, uma tabela que contenha esses valores não poderia ser lida. Além disso, JSON não pode ser envolvido em Nullable, de modo que um NULL SQL em uma coluna NULLABLE não seria preservado. O mapeamento para String não perde dados; objetos de nível superior podem ser convertidos com CAST(value AS JSON).
  • Valores BIGNUMERIC com mais de 38 dígitos na parte inteira não cabem em Decimal(76, 38) e geram um erro.
  • Valores TIMESTAMP e DATE fora do intervalo de DateTime64/Date32 (anos de 1900 a 2299) não são compatíveis.
  • Colunas RANGE são somente leitura. tabledata.insertAll espera um valor RANGE<T> como um objeto estruturado {start, end}, que não pode ser reconstruído a partir do mapeamento para String; portanto, a inserção em uma coluna RANGE gera um erro.
  • Valores INT64 são enviados para tabledata.insertAll como strings decimais, pois a API interpreta números JSON como doubles e, caso contrário, corromperia valores fora de [-2^53 + 1, 2^53 - 1].

Exemplos

Leia um conjunto de dados público usando um token do gcloud:
Leia uma tabela privada usando um arquivo de chave de conta de serviço:
Inserir dados (inserção em streaming, requer faturamento habilitado):
Use uma coleção nomeada:

Limitações

  • Somente tabelas nativas do BigQuery podem ser lidas. Views e tabelas externas exigem a execução de um job de consulta do BigQuery, o que esta função não faz.
  • Colunas RANGE podem ser lidas (como String), mas não gravadas: inserir em uma coluna RANGE gera um erro.
  • Um valor GEOGRAPHY que seja uma GEOMETRYCOLLECTION ou uma geometria vazia não pode ser representado pelo tipo Geometry; portanto, a leitura de uma linha que contenha um desses valores gera um erro. Gravar um Geometry NULL em um campo GEOGRAPHY REQUIRED, ou como elemento de um campo GEOGRAPHY REPEATED, é rejeitado, pois o BigQuery não aceita NULL nesses casos.
  • Os predicados não são enviados para baixo: tabledata.list apenas lista as linhas de uma tabela e não tem nenhum parâmetro de filtragem (aceita opções de paginação, seleção de colunas e formato), e a filtragem exigiria a execução de um job de consulta do BigQuery, o que esta função não faz. Portanto, uma condição WHERE é aplicada no ClickHouse depois que as linhas são baixadas; use a seleção de colunas para reduzir os dados transferidos.
  • Por outro lado, um LIMIT reduz a quantidade de dados lidos. As páginas são solicitadas sob demanda, com maxResults definido como max_block_size, e nenhuma página adicional é solicitada quando a consulta já tem linhas suficientes. Para um LIMIT n trivial (sem WHERE, GROUP BY, ORDER BY e com n menor que max_block_size), o ClickHouse reduz max_block_size para n, de modo que é feita exatamente uma solicitação para exatamente n linhas; caso contrário, a leitura é interrompida no primeiro limite de página após o limite, excedendo-o em menos de uma página.
  • A leitura fica vinculada ao schema observado no momento da análise da consulta, passando a lista explícita de colunas para tabledata.list. Para uma leitura muito ampla cuja lista de colunas excederia o limite de comprimento da URL da solicitação (por exemplo, SELECT * de uma tabela com milhares de colunas), a consulta é rejeitada em vez de ser executada sem essa vinculação (uma leitura sem vinculação poderia ser desalinhada por uma alteração concorrente no schema); selecione menos colunas para que a lista caiba. O mesmo limite de comprimento da URL é verificado antes de cada solicitação paginada (cada página inclui um pageToken opaco); portanto, uma leitura cujas páginas posteriores não caibam no limite é rejeitada com o mesmo erro, em vez de falhar no meio do processo.
  • Se a tabela do BigQuery for alterada depois que seu schema tiver sido lido, a consulta será rejeitada em vez de retornar ou gravar dados incompatíveis silenciosamente: o schema atual é buscado novamente e comparado ao analisado imediatamente antes de uma leitura e novamente antes que um INSERT transmita sua primeira linha. A janela restante — uma alteração no schema entre essa verificação e as solicitações subsequentes — não pode ser eliminada, pois o schema e os dados são buscados por solicitações REST separadas.
  • A comparação é feita com o snapshot do schema usado na análise da consulta, obtido quando a função de tabela resolve sua estrutura ou, no caso de uma tabela persistente (uma tabela com engine BigQuery ou uma tabela criada com CREATE TABLE ... AS bigquery(...), que persiste suas colunas da mesma forma), em sua primeira leitura ou gravação após CREATE, ATTACH ou uma reinicialização do servidor. Os metadados da tabela persistem as colunas mapeadas do ClickHouse, e não o schema do BigQuery; portanto, uma alteração no schema feita enquanto a tabela estava desanexada (ou o servidor estava inativo) é adotada pela próxima consulta em vez de ser rejeitada: as colunas declaradas ainda são validadas em relação ao schema atual, e as linhas são decodificadas com base nele, de modo que uma alteração que preserve os tipos mapeados do ClickHouse (STRING para BYTES, por exemplo) seja lida segundo as regras do novo tipo, mantendo o mesmo tipo de coluna.
  • As linhas gravadas com inserts de streaming chegam ao buffer de streaming do BigQuery e podem levar algum tempo para se tornarem visíveis em leituras subsequentes.
  • Um INSERT grande é enviado para tabledata.insertAll em batches: no máximo 500 linhas por solicitação, além de ser dividido para que cada solicitação permaneça abaixo do limite de tamanho de 10 MB do BigQuery (uma única linha maior que esse limite é rejeitada com um erro claro).
  • As operações de gravação não são atômicas, e uma única solicitação tabledata.insertAll pode ser parcialmente bem-sucedida: o BigQuery pode confirmar algumas linhas de uma solicitação e rejeitar outras com insertErrors. As solicitações também são confirmadas de forma independente, portanto, um lote posterior pode ser rejeitado depois que lotes anteriores forem aceitos. Em ambos os casos, a consulta relata um erro, mas as linhas já confirmadas permanecem no BigQuery. Para limitar duplicações, cada linha é enviada com um insertId estável, derivado do ID da consulta e da posição ordinal da linha no stream, que o BigQuery usa para desduplicação de melhor esforço dentro da janela de inserção por streaming. Um query_id que exceda o limite de 128 caracteres do insertId do BigQuery é submetido a hash para gerar um prefixo de comprimento fixo, que permanece estável para esse query_id. Como o insertId depende da posição ordinal, a desduplicação só é confiável quando a reexecução produz as linhas na mesma ordem: uma nova tentativa de um lote no nível de transporte é sempre segura, e reexecutar o mesmo INSERT com o mesmo query_id só desduplica se as linhas forem apresentadas na mesma ordem (por exemplo, uma inserção de thread única ou uma ordenação determinística — defina max_threads = 1 e max_insert_threads = 1 para um INSERT ... SELECT paralelo cuja ordem dos fragmentos poderia mudar entre tentativas).
Última modificação em 14 de agosto de 2026