Soluciona errores de esquema

Este documento te ayuda a diagnosticar y resolver los errores de HTTP 400 Bad Request que se producen cuando modificas esquemas de tablas de BigQuery o cuando defines o cargas estructuras de esquemas muy anidadas. Para obtener información sobre cómo usar las vistas de INFORMATION_SCHEMA para solucionar problemas de rendimiento de BigQuery, consulta Soluciona problemas con INFORMATION_SCHEMA.

Soluciona errores de discrepancia de esquemas

BigQuery devuelve un error Provided Schema does not match Table (reason: invalid) cuando una de las siguientes operaciones proporciona un esquema que entra en conflicto con el esquema existente de la tabla de destino:

  • Un trabajo de carga
  • Un trabajo de consulta con una tabla de destino
  • Un trabajo de copia
  • Una sentencia DDL ALTER TABLE
  • Una actualización de metadatos de tabla (tables.update o tables.patch)

Para identificar la causa y la resolución específicas, haz coincidir tu mensaje de error con una de las siguientes situaciones.

Falta el campo en el esquema nuevo

Mensaje de error

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Field FIELD_NAME is missing in new schema

Diagnóstico

Una de las siguientes operaciones proporciona una definición de esquema que omite una o más columnas que ya existen en la tabla de destino:

  • Un trabajo de carga
  • Una operación de escritura de DataFrame
  • Una llamada a la API tables.update o tables.patch

Solución

BigQuery no permite descartar columnas de forma implícita omitiéndolas de una carga útil de esquema de API o de una configuración de trabajo de carga. Para resolver este error, realiza una de las siguientes acciones:

  • Actualiza tu canalización o solicitud a la API para que el esquema proporcionado incluya todas las columnas existentes en la tabla de destino.
  • Si quieres quitar la columna de la tabla, ejecuta una declaración DDL DROP COLUMN en lugar de omitir la columna de una solicitud de carga o de parche:

    ALTER TABLE `PROJECT_ID.DATASET.TABLE`
    DROP COLUMN FIELD_NAME;

    Reemplaza lo siguiente:

    • PROJECT_ID: el ID del proyecto que contiene la tabla.
    • DATASET: Es el nombre del conjunto de datos que contiene la tabla.
    • TABLE: Es el nombre de la tabla.
    • FIELD_NAME: Es el nombre de la columna que se descartará.

El campo cambió de tipo

Mensaje de error

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Field FIELD_NAME has changed type from EXISTING_TYPE to NEW_TYPE

Diagnóstico

Tu solicitud intenta cambiar el tipo de datos de una columna existente (por ejemplo, de STRING a INT64) durante un trabajo de carga o una actualización de esquema.

Solución

Para resolver este error, haz lo siguiente:

  • Si el cambio de tipo es una conversión de tipo de datos de columna admitida (como INT64 a NUMERIC, INT64 a FLOAT64 o NUMERIC a BIGNUMERIC), usa una declaración DDL ALTER TABLE ... ALTER COLUMN:

    ALTER TABLE `PROJECT_ID.DATASET.TABLE`
    ALTER COLUMN FIELD_NAME SET DATA TYPE NEW_TYPE;

    Reemplaza lo siguiente:

    • PROJECT_ID: el ID del proyecto que contiene la tabla.
    • DATASET: Es el nombre del conjunto de datos que contiene la tabla.
    • TABLE: Es el nombre de la tabla.
    • FIELD_NAME: Es el nombre de la columna que se modificará.
    • NEW_TYPE: el tipo de datos de destino.
  • Si la conversión de tipo no se admite in situ, consulta los datos existentes con una expresión CAST explícita y escribe los resultados en una tabla nueva o reemplaza la tabla existente. Para obtener más información, consulta Cambia el tipo de datos de una columna.

El campo cambió de modo

Mensaje de error

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Field FIELD_NAME has changed mode from EXISTING_MODE to NEW_MODE

Diagnóstico

Tu solicitud intenta un cambio de modo de columna no admitido (por ejemplo, cambiar NULLABLE a REQUIRED o REPEATED a NULLABLE). Este error también se produce si usas una definición de esquema intercalada en la herramienta de línea de comandos de bq cuando flexibilizas una columna REQUIRED en una tabla que contiene columnas REPEATED, porque las definiciones de esquema intercaladas en la herramienta de línea de comandos de bq no admiten la modificación de tablas con columnas REPEATED.

Solución

El único cambio de modo que admiten las actualizaciones de esquemas de BigQuery en el lugar es flexibilizar el modo de una columna de REQUIRED a NULLABLE. Para resolver este error, realiza una de las siguientes acciones:

  • Si flexibilizas una columna de REQUIRED a NULLABLE, ejecuta una declaración de DDL ALTER TABLE ... ALTER COLUMN ... DROP NOT NULL en GoogleSQL o proporciona un archivo de esquema JSON si actualizas el esquema con el comando bq update o el método de la API de tables.patch. Para obtener instrucciones, consulta Cambia el modo de una columna.
  • Para cambiar el modo de una columna de NULLABLE a REQUIRED o de REPEATED a NULLABLE, crea una tabla nueva con el esquema actualizado y copia o carga los datos en la tabla nueva. Para obtener instrucciones, consulta Modifica esquemas de tablas.

No se pueden agregar campos

Mensaje de error

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Cannot add fields (field: FIELD_NAME)

Diagnóstico

Un trabajo de carga o de consulta incluye una columna (FIELD_NAME) que no existe en la tabla de destino, y la adición de esquemas no está habilitada en la configuración del trabajo.

Solución

Habilita la adición de esquemas en el trabajo de carga o consulta:

  • En la API de REST o las bibliotecas cliente, incluye ALLOW_FIELD_ADDITION en la propiedad schemaUpdateOptions de la configuración de tu trabajo de carga o consulta.
  • En la herramienta de línea de comandos de bq, pasa la marca --schema_update_option=ALLOW_FIELD_ADDITION.
  • Como alternativa, agrega la columna antes de ejecutar el trabajo con ALTER TABLE ... ADD COLUMN.

No se pueden agregar campos obligatorios a un esquema existente

Mensaje de error

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Cannot add required fields to an existing schema. (field: FIELD_NAME)

Diagnóstico

Tu solicitud agrega una columna nueva a una tabla existente con el modo de columna establecido en REQUIRED (NOT NULL). Debido a que las filas existentes en la tabla recibirían valores NULL para la columna recién agregada, BigQuery rechaza agregar columnas REQUIRED directamente a través de actualizaciones de esquema.

Solución

Para resolver este error, haz lo siguiente:

  • Agrega la columna nueva con el modo NULLABLE en lugar de REQUIRED y, luego, ejecuta una sentencia DML UPDATE para propagar los valores de las filas existentes.
  • Para agregar la columna y asignar un valor predeterminado, completa los siguientes pasos:

    1. Agrega la columna como una columna NULLABLE.
    2. Establece el valor predeterminado de la columna para que las inserciones futuras reciban un valor automáticamente.
    3. Actualiza las filas existentes para propagar el valor predeterminado:

      ALTER TABLE `PROJECT_ID.DATASET.TABLE`
      ADD COLUMN FIELD_NAME DATA_TYPE;
      
      ALTER TABLE `PROJECT_ID.DATASET.TABLE`
      ALTER COLUMN FIELD_NAME SET DEFAULT DEFAULT_EXPRESSION;
      
      UPDATE `PROJECT_ID.DATASET.TABLE`
      SET FIELD_NAME = DEFAULT_EXPRESSION
      WHERE TRUE;

      Reemplaza lo siguiente:

      • PROJECT_ID: el ID del proyecto que contiene la tabla.
      • DATASET: Es el nombre del conjunto de datos que contiene la tabla.
      • TABLE: Es el nombre de la tabla.
      • FIELD_NAME: Es el nombre de la columna nueva.
      • DATA_TYPE: Es el tipo de datos de la columna.
      • DEFAULT_EXPRESSION: Es la expresión de valor predeterminada para la columna.

El campo ya existe en el esquema

Mensaje de error

Field FIELD_NAME already exists in schema

Diagnóstico

El esquema proporcionado en la solicitud a la API, el archivo de esquema JSON o el encabezado del archivo de origen (como CSV o Parquet) contiene nombres de columnas duplicados. Los nombres de las columnas en BigQuery no distinguen mayúsculas de minúsculas, por lo que especificar Field_A y field_a en el mismo esquema activa este error.

Solución

Inspecciona el esquema de origen y quita o cambia el nombre de las columnas duplicadas, incluidas las colisiones de nombres que no distinguen mayúsculas de minúsculas.

No se admite la actualización de la intercalación de campos

Mensaje de error

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Invalid schema update. Updating field collation is not supported. Field FIELD_NAME has changed collation from "EXISTING_COLLATION" to "NEW_COLLATION"

Diagnóstico

No puedes modificar ni quitar la especificación de intercalación de una columna existente durante una actualización del esquema. Este error suele ocurrir cuando una aplicación recupera el esquema de una tabla, modifica otro campo y vuelve a escribir el esquema con una versión anterior de la biblioteca cliente que no conserva la propiedad del campo collation (envía "" en lugar de "und:ci").

Solución

Para resolver este error, haz lo siguiente:

  • Actualiza la biblioteca cliente de BigQuery a la versión más reciente para que se conserven los atributos collation existentes cuando se lean y se apliquen parches en los metadatos de la tabla.
  • Si creas cargas útiles de esquemas JSON de forma manual, asegúrate de que la propiedad collation en las columnas existentes coincida con el esquema actual de la tabla.

No se admite la reducción de parámetros de tipo

Mensaje de error

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Narrowing type parameters is not compatible

Diagnóstico

Tu sentencia ALTER TABLE ... ALTER COLUMN ... SET DATA TYPE intenta reducir la longitud, la precisión o la escala máximas de un tipo de datos parametrizado, por ejemplo, cambiar STRING(100) a STRING(50) o reducir los parámetros NUMERIC(P, S).

Solución

BigQuery solo permite ampliar los parámetros de tipo en una columna existente (como aumentar STRING(50) a STRING(100)). Para aplicar parámetros de tipo más estrechos, crea una tabla nueva definida con el parámetro de tipo más estrecho y copia o carga los datos en la tabla nueva con una consulta SELECT que haga que los valores se ajusten al tipo más estrecho (por ejemplo, LEFT(FIELD_NAME, 50) para una columna STRING). Si escribes un valor STRING o BYTES más largo que la longitud máxima de la columna, o un valor NUMERIC con más dígitos que los que permite su precisión, se mostrará un error. Los valores NUMERIC con más dígitos decimales que la escala de la columna se redondean. Para obtener más información, consulta Modifica esquemas de tablas.

No se admite agregar un campo con un valor predeterminado

Mensaje de error

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Add field with default value to an existing table schema is not supported; Field: FIELD_NAME. ...

Diagnóstico

Tu trabajo de carga o solicitud a la API de tables.patch o tables.update intenta agregar una columna nueva a una tabla existente mientras se especifica defaultValueExpression en la carga útil del esquema de API. No puedes agregar una columna nueva con un valor predeterminado a una tabla existente en una sola actualización del esquema de API.

Solución

En lugar de especificar defaultValueExpression cuando agregas la columna en la solicitud a la API, agrega la columna primero y, luego, establece su valor predeterminado (para obtener más información, consulta Limitaciones):

  • Si aún no agregaste la columna, ejecuta las siguientes sentencias y, luego, reanuda las cargas sin defaultValueExpression:

    ALTER TABLE `PROJECT_ID.DATASET.TABLE`
    ADD COLUMN FIELD_NAME DATA_TYPE;
    
    ALTER TABLE `PROJECT_ID.DATASET.TABLE`
    ALTER COLUMN FIELD_NAME SET DEFAULT DEFAULT_EXPRESSION;
    
    UPDATE `PROJECT_ID.DATASET.TABLE`
    SET FIELD_NAME = DEFAULT_EXPRESSION
    WHERE TRUE;

    Reemplaza lo siguiente:

    • PROJECT_ID: el ID del proyecto que contiene la tabla.
    • DATASET: Es el nombre del conjunto de datos que contiene la tabla.
    • TABLE: Es el nombre de la tabla.
    • FIELD_NAME: Es el nombre de la columna nueva.
    • DATA_TYPE: Es el tipo de datos de la columna.
    • DEFAULT_EXPRESSION: Es la expresión de valor predeterminada para la columna.
  • Si ya agregaste la columna volviendo a enviar la solicitud sin defaultValueExpression, ejecuta solo las declaraciones ALTER COLUMN ... SET DEFAULT y UPDATE del ejemplo anterior.

No se admite la actualización de los atributos de una columna de identidad existente

Mensaje de error

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Updating an existing identity column's attributes is not supported. Field FIELD_NAME already has identity column info.

Diagnóstico

Tu solicitud intenta modificar los atributos de una columna de identidad existente a través de una actualización de esquema o un parche de la API.

Solución

Las propiedades de la columna de identidad no se pueden modificar in situ después de la creación. Mantén sin cambios la definición de la columna de identidad existente en la carga útil de actualización del esquema o crea una tabla nueva con la configuración de la columna de identidad actualizada y copia o carga los datos en la tabla nueva. Para obtener instrucciones, consulta Modifica esquemas de tablas.

Cambio de campo incompatible dentro de la columna RECORD

Mensaje de error

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Incompatible field change within RECORD column

Diagnóstico

Tu sentencia ALTER TABLE ... ALTER COLUMN ... SET DATA TYPE especifica un tipo STRUCT que no es compatible con el tipo existente de la columna. Por ejemplo, el tipo nuevo agrega o quita subcampos, cambia un subcampo a un tipo no admitido o restringe los parámetros de tipo de un subcampo.

Solución

Compara el tipo STRUCT en tu sentencia ALTER TABLE con el esquema existente de la columna y, luego, realiza una de las siguientes acciones:

Se alcanzó el límite máximo de esquemas físicos divergentes

Mensaje de error

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Maximum limit on diverging physical schemas reached.

Diagnóstico

Ciertas modificaciones del esquema de la tabla, como descartar o cambiar el nombre de las columnas, pueden hacer que las tablas tengan esquemas lógicos idénticos en la API, mientras que tienen diferentes representaciones de esquemas físicos subyacentes. Cuando copias datos en una tabla de destino en demasiadas versiones de esquemas físicos divergentes, el trabajo de copia de la tabla puede fallar con este error. Para obtener más información, consulta Limitaciones para copiar tablas.

Solución

Usa la declaración DDL CREATE TABLE LIKE para volver a crear la tabla de destino de modo que su representación de esquema físico coincida con el esquema de la tabla de origen y, luego, copia o inserta los datos:

CREATE OR REPLACE TABLE `PROJECT_ID.DATASET.DESTINATION_TABLE`
LIKE `PROJECT_ID.DATASET.SOURCE_TABLE`;

INSERT INTO `PROJECT_ID.DATASET.DESTINATION_TABLE`
SELECT * FROM `PROJECT_ID.DATASET.SOURCE_TABLE`;

Reemplaza lo siguiente:

  • PROJECT_ID: el ID del proyecto que contiene las tablas.
  • DATASET: Es el nombre del conjunto de datos que contiene las tablas.
  • DESTINATION_TABLE: Es el nombre de la tabla de destino que se volverá a crear.
  • SOURCE_TABLE: Es el nombre de la tabla de origen.

Soluciona problemas de errores de límite de anidamiento de esquemas, archivos y rutinas

BigQuery aplica una profundidad máxima de anidamiento de 15 niveles para las columnas STRUCT (RECORD), los archivos de carga estructurados y los tipos de datos que se devuelven y argumentos de rutina anidados. Si se supera este límite de 15 niveles, se muestra un error HTTP 400 Bad Request con uno de los siguientes mensajes (en los que MAX_DEPTH y MAX_LEVEL son 15). Para ver los errores causados por superar el límite de 16 niveles de anidamiento en vistas lógicas o funciones persistentes definidas por el usuario (UDF), consulta Demasiadas vistas anidadas o funciones persistentes definidas por el usuario.

Mensajes de error

  • Schema nested too deeply.
  • Schema nested too deeply for field FIELD_NAME, maximum allowed depth is MAX_DEPTH.
  • Field 'FIELD_NAME' is nested too deeply. It has definition level LEVEL while maximum allowed definition level is MAX_LEVEL.
  • Schema nested too deeply, at least LEVEL compared to the maximum allowed level of 15.
  • Routine TYPE_DESCRIPTION nested too deeply; max allowed depth: MAX_DEPTH

Diagnóstico

Las columnas de tipo STRUCT (RECORD) pueden contener campos RECORD anidados hasta una profundidad máxima de 15 niveles, independientemente de si los campos son escalares (NULLABLE o REQUIRED) o basados en arrays (REPEATED). Del mismo modo, los trabajos de carga y las tablas externas de JSON, Parquet y Avro aplican el límite de anidamiento cuando analizan estructuras anidadas. Para los archivos Parquet, el límite se expresa como un nivel de definición máximo y un nivel de repetición máximo.

En los errores de rutina, TYPE_DESCRIPTION identifica el tipo anidado: argument type, return type o return table type.

Solución

Este límite no se puede aumentar. Para resolver este error, haz lo siguiente:

  • Aplanar la definición del tipo de esquema o rutina. Divide las jerarquías STRUCT o ARRAY con un nivel de anidamiento profundo en el esquema de la tabla o en los tipos de datos que se devuelven y los argumentos de la rutina en tablas relacionadas independientes y únelas en el momento de la consulta, o bien promueve los atributos con un nivel de anidamiento profundo a columnas de nivel superior.
  • Usa el tipo de datos JSON integrado. Si tus datos requieren más de 15 niveles de anidamiento, almacena los subárboles con anidamiento profundo en una columna de tipo JSON (o STRING). Una columna JSON se almacena como una sola columna en el esquema de la tabla, lo que evita el límite de esquema RECORD de 15 niveles, a la vez que te permite extraer rutas de acceso con anidamiento profundo en el momento de la consulta con operadores y funciones de acceso a campos JSON.
  • Preprocesa los archivos de entrada antes de cargarlos. Si el error se produce durante un trabajo de carga desde archivos JSON, Parquet o Avro en Cloud Storage, agrega un paso de procesamiento previo ascendente para compactar o serializar estructuras con más de 15 niveles antes de cargarlas en BigQuery.