SELECT e INSERT en una tabla de Google BigQuery, incluidos los conjuntos de datos públicos. La estructura de la tabla se infiere automáticamente a partir de su esquema en BigQuery.
La lectura utiliza la API REST de BigQuery (tabledata.list), por lo que solo se pueden leer tablas nativas; no se admiten vistas, vistas materializadas ni tablas externas. La escritura utiliza inserciones en streaming (tabledata.insertAll), lo que requiere tener habilitada la facturación en el proyecto.
Sintaxis
Argumentos
Los argumentos
project, dataset, table y access_token también se pueden proporcionar en formato key = value; los argumentos posicionales ocupan estas posiciones en este orden, y especificar un argumento tanto por posición como mediante una clave (o especificar la misma clave dos veces) produce un error.
Los siguientes argumentos se pueden especificar en formato key = value (o como claves de una colección con nombre):
Autenticación
- Token de acceso. Cualquier token de acceso OAuth 2.0 válido; por ejemplo, obtenido con
gcloud auth print-access-token. Los tokens caducan rápidamente (por lo general, después de una hora), por lo que este método es más adecuado para el uso interactivo. - Clave de cuenta de servicio (recomendada para servidores). Pase el contenido de un archivo de clave creado en Google Cloud IAM mediante el argumento
service_account_key. ClickHouse firma un JWT con la clave y lo intercambia por un token de acceso, que renueva automáticamente. - Token de actualización. Pase
client_id,client_secretyrefresh_token; por ejemplo, obtenidos de~/.config/gcloud/application_default_credentials.jsondespués de ejecutargcloud auth application-default login.
BigQuery o CREATE TABLE ... AS bigquery(...)) se registra como dependencia de la colección, por lo que DROP NAMED COLLECTION queda bloqueado mientras exista la tabla.
Correspondencia de tipos de datos
Notas:
DATETIMEde BigQuery no tiene zona horaria; se asigna aDateTime64(6, 'UTC')para que el valor mostrado no dependa de la zona horaria del servidor.- Un
RECORDNULLABLEse asigna aNullable(Tuple(...)), de modo que unNULLde todo el registro se conserva comoNULLen lugar de reducirse a unTuplede valores predeterminados. Un arrayNULL(o vacío) se convierte en un array vacío, porqueArrayno puede estar dentro deNullableen ClickHouse. Un array de BigQuery no puede contener elementosNULL(ARRAY<T>equivale aARRAY<T NOT NULL>), por lo que el tipo de elemento de un campoREPEATEDno esNullable(Array(T)oArray(Tuple(...))para un elementoRECORD); un elementoNULLen una respuesta detabledata.listse rechaza como entrada malformada. - La lectura y escritura de columnas
Nullable(Tuple(...))mediante la función de tablabigqueryfunciona sin configuraciones adicionales. Para crear una tabla persistente con engineBigQueryque contenga una columna de este tipo (tanto si la estructura se infiere como si se declara explícitamente), se requiere la configuraciónenable_nullable_tuple_type, como para cualquier columnaNullable(Tuple). Al declarar columnas explícitamente, un campoRECORDpuede declararse como unTuple(...)simple para evitar esta configuración, a costa de convertir unNULLde todo el registro en una tupla predeterminada; la única diferencia aceptada respecto al tipo inferido es eliminar elNullableque envuelve elTuplede unRECORD, y únicamente en ese mismo registro: la anulabilidad no puede trasladarse a un registro distinto, ya sea interno o externo. GEOGRAPHYse asigna a Geometry. BigQuery transfiere un valorGEOGRAPHYcomo texto WKT, que se analiza como la alternativa correspondiente deGeometry(unVariantdePoint,MultiPoint,Ring,LineString,MultiLineString,PolygonyMultiPolygon) durante la lectura y se serializa de nuevo como WKT durante la escritura. UnaGEOMETRYCOLLECTIONy una geometría vacía (comoPOINT EMPTY) no tienen equivalente enGeometry, por lo que leer una fila que contenga alguno de estos valores genera un error. ComoVariantya admiteNULL, un campoGEOGRAPHYNULLABLEse asigna aGeometryy no aNullable(Geometry), yNULLsigue conservándose en el recorrido de ida y vuelta.JSONse asigna aStringen lugar del tipo de datos JSON, porque el tipoJSONde ClickHouse solo acepta un objeto ({...}) en el nivel superior, mientras que un valorJSONde BigQuery puede ser cualquier valor JSON —un escalar, un array onull—, por lo que no se podría leer una tabla que contenga dichos valores. Además,JSONno puede envolverse enNullable, por lo que unNULLde SQL en una columnaNULLABLEno se conservaría. La correspondencia conStringno pierde información; los objetos de nivel superior se pueden convertir conCAST(value AS JSON).- Los valores
BIGNUMERICcon más de 38 dígitos en la parte entera no caben enDecimal(76, 38)y generan un error. - Los valores
TIMESTAMPyDATEfuera del rango deDateTime64/Date32(años 1900-2299) no son compatibles. - Las columnas
RANGEson de solo lectura.tabledata.insertAllespera un valorRANGE<T>como un objeto estructurado{start, end}, que no se puede reconstruir a partir de la correspondencia conString, por lo que insertar en una columnaRANGEgenera un error. - Los valores
INT64se envían atabledata.insertAllcomo cadenas decimales, porque la API analiza los números JSON como valores de doble precisión y, de otro modo, corrompería los valores fuera de[-2^53 + 1, 2^53 - 1].
Ejemplos
gcloud:
Limitaciones
- Solo se pueden leer tablas nativas de BigQuery. Las vistas y las tablas externas requieren ejecutar un trabajo de consulta de BigQuery, algo que esta función no hace.
- Las columnas
RANGEse pueden leer (comoString), pero no se pueden escribir: insertar en una columnaRANGEgenera un error. - Un valor
GEOGRAPHYque sea unaGEOMETRYCOLLECTIONo una geometría vacía no puede representarse mediante el tipoGeometry, por lo que leer una fila que contenga uno de estos valores genera un error. Se rechaza escribir unGeometryNULLen un campoGEOGRAPHYREQUIRED, o como elemento de un campoGEOGRAPHYREPEATED, porque BigQuery no admite valoresNULLen esos casos. - No se hace pushdown de predicados:
tabledata.listsolo enumera las filas de una tabla y no dispone de ningún parámetro de filtrado (admite opciones de paginación, selección de columnas y formato), y filtrar requeriría ejecutar un trabajo de consulta de BigQuery, algo que esta función no hace. Por lo tanto, una condiciónWHEREse aplica en ClickHouse después de descargar las filas; use la selección de columnas para reducir los datos transferidos. - En cambio, un
LIMITsí reduce la cantidad de datos leídos. Las páginas se solicitan de forma diferida, conmaxResultsestablecido enmax_block_size, y no se solicita ninguna página adicional cuando la consulta ya tiene suficientes filas. Para unLIMIT ntrivial (sinWHERE,GROUP BYniORDER BY, y conninferior amax_block_size), ClickHouse reducemax_block_sizean, por lo que se realiza exactamente una solicitud de exactamentenfilas; de lo contrario, la lectura se detiene en el primer límite de página posterior al límite, superándolo en menos de una página. - La lectura queda fijada al esquema observado en el momento del análisis de la consulta al pasar la lista explícita de columnas a
tabledata.list. Para una lectura muy amplia cuya lista de columnas exceda el límite de longitud de la URL de la solicitud (por ejemplo,SELECT *de una tabla con miles de columnas), la consulta se rechaza en lugar de leer sin fijación (una lectura sin fijación podría desalinearse debido a un cambio de esquema concurrente); seleccione menos columnas para que la lista quepa. El mismo límite de longitud de URL se comprueba antes de cada solicitud paginada (cada página incluye unpageTokenopaco), por lo que una lectura cuyas páginas posteriores no quepan dentro del límite se rechaza con el mismo error en lugar de fallar a mitad del proceso. - Si la tabla de BigQuery se modifica después de leer su esquema, la consulta se rechaza en lugar de devolver o escribir silenciosamente datos no coincidentes: el esquema actual se vuelve a obtener y se compara con el analizado justo antes de una lectura, y de nuevo antes de que un
INSERTtransmita su primera fila. La ventana restante (un cambio de esquema entre esa comprobación y las solicitudes posteriores) no puede eliminarse, porque el esquema y los datos se obtienen mediante solicitudes REST independientes. - La comparación se realiza con la instantánea del esquema con la que se analizó la consulta, que se toma cuando la función de tabla resuelve su estructura o, en el caso de una tabla persistente (una tabla con engine
BigQuery, o una tabla creada conCREATE TABLE ... AS bigquery(...), que conserva sus columnas de la misma forma), en su primera lectura o escritura después deCREATE,ATTACHo un reinicio del servidor. Los metadatos de la tabla conservan las columnas de ClickHouse asignadas, no el esquema de BigQuery, por lo que un cambio de esquema realizado mientras la tabla estaba separada (o el servidor estaba apagado) es adoptado por la siguiente consulta en lugar de rechazarse: las columnas declaradas siguen validándose con respecto al esquema actual y las filas se decodifican con él, por lo que un cambio que conserve los tipos de ClickHouse asignados (deSTRINGaBYTES, por ejemplo) se lee según las reglas del nuevo tipo bajo el mismo tipo de columna. - Las filas escritas mediante inserciones de streaming llegan al búfer de streaming de BigQuery y pueden tardar un tiempo en ser visibles en lecturas posteriores.
- Un
INSERTgrande se envía atabledata.insertAllen lotes: como máximo 500 filas por solicitud, y también se divide para que cada solicitud se mantenga por debajo del límite de tamaño de solicitud de 10 MB de BigQuery (una sola fila que supere ese límite se rechaza con un error claro). - Las operaciones de escritura no son atómicas y una sola solicitud
tabledata.insertAllpuede completarse parcialmente: BigQuery puede confirmar algunas filas de una solicitud y rechazar otras coninsertErrors. Además, las solicitudes se confirman de forma independiente, por lo que un lote posterior puede rechazarse después de que se hayan aceptado lotes anteriores. En ambos casos, la consulta informa de un error, pero las filas ya confirmadas permanecen en BigQuery. Para limitar los duplicados, cada fila se envía con uninsertIdestable derivado del id de consulta y de la posición ordinal de la fila en el flujo, que BigQuery utiliza para realizar una deduplicación de máximo esfuerzo dentro de su ventana de inserciones en streaming. Si unquery_idsupera el límite de 128 caracteres de BigQuery parainsertId, se le aplica hash para obtener un prefijo de longitud fija que se mantiene estable para esequery_id. Dado que elinsertIddepende de la posición ordinal, la deduplicación solo es fiable cuando la reejecución produce las filas en el mismo orden: reintentar un lote a nivel de transporte siempre es seguro, y volver a ejecutar el mismoINSERTcon el mismoquery_idsolo deduplica si presenta las filas en el mismo orden (por ejemplo, mediante una inserción de un solo hilo o un orden determinista; establezcamax_threads = 1ymax_insert_threads = 1para unINSERT ... SELECTparalelo cuyo orden de fragmentos podría cambiar entre intentos).