排解結構定義錯誤

本文可協助您診斷及解決 HTTP 400 Bad Request 錯誤。這類錯誤會在您修改 BigQuery 資料表結構定義,或定義/載入深度巢狀結構定義時發生。如要瞭解如何使用 INFORMATION_SCHEMA 檢視表排解 BigQuery 效能問題,請參閱「使用資訊結構定義排解問題」。

排解結構定義不符錯誤

如果下列任一作業提供的結構定義與目標資料表的現有結構定義衝突,BigQuery 會傳回 Provided Schema does not match Table 錯誤 (reason: invalid):

  • 載入工作
  • 含有目的地資料表的查詢工作
  • 複製工作
  • ALTER TABLE DDL 陳述式
  • 資料表中繼資料更新 (tables.update 或 tables.patch)

如要找出具體原因和解決方法,請將錯誤訊息與下列其中一種情況進行比對。

新結構定義缺少欄位

錯誤訊息

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

診斷

下列其中一項作業提供的結構定義,省略了目的地資料表中已存在的一或多個資料欄:

  • 載入工作
  • DataFrame 寫入作業
  • tables.update 或 tables.patch API 呼叫

解析度

BigQuery 不允許透過從 API 架構酬載或載入工作設定中省略資料欄,來隱含刪除資料欄。如要解決這個錯誤,請執行下列任一操作:

  • 請更新管道或 API 要求,確保提供的結構定義包含目標資料表中的所有現有資料欄。
  • 如要從資料表中移除資料欄,請執行 DROP COLUMN DDL 陳述式,而非在載入或修補要求中省略資料欄:

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

    更改下列內容:

    • PROJECT_ID:資料表所在專案的 ID。
    • DATASET:資料表所在的資料集名稱。
    • TABLE:資料表名稱。
    • FIELD_NAME:要捨棄的資料欄名稱。

欄位類型已變更

錯誤訊息

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

診斷

您的要求嘗試在載入工作或結構定義更新期間,就地變更現有資料欄的資料類型 (例如從 STRING 變更為 INT64)。

解析度

如要解決這個錯誤,請執行下列任一操作:

  • 如果類型變更是支援的資料欄資料類型轉換 (例如 INT64 轉換為 NUMERIC、INT64 轉換為 FLOAT64,或 NUMERIC 轉換為 BIGNUMERIC),請使用 ALTER TABLE ... ALTER COLUMN DDL 陳述式:

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

    更改下列內容:

    • PROJECT_ID:資料表所在專案的 ID。
    • DATASET:資料表所在的資料集名稱。
    • TABLE:資料表名稱。
    • FIELD_NAME:要修改的資料欄名稱。
    • NEW_TYPE:目標資料類型。
  • 如果無法就地轉換類型,請使用明確的 CAST 運算式查詢現有資料,並將結果寫入新的資料表,或覆寫現有資料表。詳情請參閱「變更資料欄的資料類型」。

欄位已變更模式

錯誤訊息

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

診斷

您的要求嘗試變更不支援的資料欄模式 (例如將 NULLABLE 變更為 REQUIRED,或將 REPEATED 變更為 NULLABLE)。如果您在 bq 指令列工具中使用內嵌結構定義定義,放寬包含 REPEATED 資料欄的資料表上的 REQUIRED 資料欄,也會發生這項錯誤,因為 bq 指令列工具中的內嵌結構定義定義不支援修改包含 REPEATED 資料欄的資料表。

解析度

就地更新 BigQuery 結構定義時,唯一支援的模式變更,是將資料欄模式從 REQUIRED 放寬為 NULLABLE。如要解決這個錯誤,請按照下列其中一種做法進行:

  • 如要將資料欄從 REQUIRED 寬鬆為 NULLABLE,請在 GoogleSQL 中執行 ALTER TABLE ... ALTER COLUMN ... DROP NOT NULL DDL 陳述式,或是在使用 bq update 指令或 tables.patch API 方法更新結構定義時,提供 JSON 結構定義檔案。如需操作說明,請參閱「變更資料欄模式」。
  • 如要將資料欄模式從 NULLABLE 變更為 REQUIRED,或從 REPEATED 變更為 NULLABLE,請建立具有更新結構定義的新資料表,然後將資料複製或載入新資料表。如需操作說明,請參閱「修改資料表結構定義」。

無法新增欄位

錯誤訊息

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

診斷

載入工作或查詢工作包含目的地資料表中不存在的資料欄 (FIELD_NAME),且工作設定中未啟用結構定義新增功能。

解析度

在載入或查詢工作中啟用結構定義新增功能:

  • 在 REST API 或用戶端程式庫中,請在載入或查詢工作設定的 schemaUpdateOptions 屬性中加入 ALLOW_FIELD_ADDITION。
  • 在 bq 指令列工具中,傳遞 --schema_update_option=ALLOW_FIELD_ADDITION 旗標。
  • 或者,您也可以使用 ALTER TABLE ... ADD COLUMN,在執行工作前新增資料欄。

無法在現有結構定義中新增必要欄位

錯誤訊息

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

診斷

您的要求會將新資料欄附加至現有資料表,並將資料欄模式設為 REQUIRED (NOT NULL)。由於資料表中的現有資料列會收到新加入資料欄的 NULL 值,BigQuery 會拒絕直接透過結構定義更新新增 REQUIRED 資料欄。

解析度

如要解決這個錯誤,請執行下列任一操作:

  • 新增模式為 NULLABLE 而非 REQUIRED 的新資料欄,然後執行 DML UPDATE 陳述式,為現有資料列填入值。
  • 如要新增資料欄並指派預設值,請完成下列步驟:

    1. 將資料欄新增為 NULLABLE 資料欄。
    2. 設定資料欄的預設值,讓日後插入的值自動接收值。
    3. 更新現有資料列,填入預設值:

      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;

      更改下列內容:

      • PROJECT_ID:資料表所在專案的 ID。
      • DATASET:資料表所在的資料集名稱。
      • TABLE:資料表名稱。
      • FIELD_NAME:新資料欄的名稱。
      • DATA_TYPE:資料欄的資料類型。
      • DEFAULT_EXPRESSION:資料欄的預設值運算式。

結構定義中已有這個欄位

錯誤訊息

Field FIELD_NAME already exists in schema

診斷

API 要求、JSON 結構定義檔案或來源檔案標頭 (例如 CSV 或 Parquet) 中提供的結構定義包含重複的資料欄名稱。BigQuery 中的資料欄名稱不區分大小寫,因此在同一個結構定義中同時指定 Field_A 和 field_a 會觸發這項錯誤。

解析度

檢查來源結構定義,並移除或重新命名重複的資料欄名稱,包括任何不區分大小寫的名稱衝突。

不支援更新欄位定序

錯誤訊息

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"

診斷

更新結構定義時,您無法修改或移除現有資料欄的定序規格。如果應用程式擷取資料表的結構定義、修改其他欄位,並使用不保留 collation 欄位屬性的舊版用戶端程式庫將結構定義寫回 (傳送 "" 而非 "und:ci"),通常就會發生這項錯誤。

解析度

如要解決這項錯誤,請執行下列操作:

  • 請將 BigQuery 用戶端程式庫升級至最新版本,以便在讀取及修補資料表中繼資料時,保留現有的 collation 屬性。
  • 如果您手動建構 JSON 結構定義酬載,請確保現有資料欄的 collation 屬性與資料表的目前結構定義相符。

不支援縮小類型參數

錯誤訊息

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

診斷

您的 ALTER TABLE ... ALTER COLUMN ... SET DATA TYPE 陳述式嘗試縮減參數化資料類型的最大長度、精確度或規模,例如將 STRING(100) 變更為 STRING(50),或減少 NUMERIC(P, S) 參數。

解析度

BigQuery 僅允許在現有資料欄中擴大類型參數 (例如將 STRING(50) 增加至 STRING(100))。如要強制執行較窄的類型參數,請建立以較窄類型參數定義的新資料表,並使用 SELECT 查詢將資料複製或載入新資料表,讓值符合較窄的類型 (例如 STRING 資料欄的 LEFT(FIELD_NAME, 50))。如果寫入的 STRING 或 BYTES 值超過資料欄長度上限,或 NUMERIC 值的位數超過精確度允許的範圍,系統會傳回錯誤。如果 NUMERIC 值的小數位數超過資料欄的規模,系統會四捨五入。詳情請參閱「修改資料表結構定義」。

不支援新增含有預設值的欄位

錯誤訊息

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. ...

診斷

您的載入工作或 tables.patch 或 tables.update API 要求嘗試在現有資料表中新增資料欄,同時在 API 架構酬載中指定 defaultValueExpression。您無法在單一 API 架構更新中,將含有預設值的新資料欄新增至現有資料表。

解析度

在 API 要求中新增資料欄時,請先新增資料欄,然後再設定預設值,而非指定 defaultValueExpression (詳情請參閱「限制」):

  • 如果您尚未新增資料欄,請執行下列陳述式,然後在不使用 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;

    更改下列內容:

    • PROJECT_ID:資料表所在專案的 ID。
    • DATASET:資料表所在的資料集名稱。
    • TABLE:資料表名稱。
    • FIELD_NAME:新資料欄的名稱。
    • DATA_TYPE:資料欄的資料類型。
    • DEFAULT_EXPRESSION:資料欄的預設值運算式。
  • 如果您已重新提交不含 defaultValueExpression 的要求來新增資料欄,請僅執行上述範例中的 ALTER COLUMN ... SET DEFAULT 和 UPDATE 陳述式。

不支援更新現有識別資訊欄的屬性

錯誤訊息

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.

診斷

您的要求嘗試透過結構定義更新或 API 修補程式,修改現有識別資訊欄的屬性。

解析度

識別欄屬性建立後,即無法就地修改。請在結構定義更新酬載中,保留現有的識別欄定義,或使用更新後的識別欄設定建立新資料表,然後將資料複製或載入新資料表。如需操作說明,請參閱「修改資料表結構定義」。

RECORD 欄內有不相容的欄位變更

錯誤訊息

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

診斷

您的 ALTER TABLE ... ALTER COLUMN ... SET DATA TYPE 陳述式指定了與資料欄現有類型不相容的 STRUCT 類型。例如,新類型會新增或移除子欄位、將子欄位變更為不支援的類型,或縮減子欄位的類型參數。

解析度

比較 ALTER TABLE 陳述式中的 STRUCT 類型與資料欄現有的結構定義,然後執行下列任一操作:

已達實體結構定義分歧上限

錯誤訊息

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

診斷

某些資料表結構定義修改作業 (例如捨棄或重新命名資料欄),可能會導致資料表在 API 中具有相同的邏輯結構定義,但基礎實體結構定義表示法不同。如果將資料複製到目的地資料表時,涉及過多不同的實體結構定義版本,資料表複製工作可能會失敗,並顯示這項錯誤。詳情請參閱「複製資料表的限制」。

解析度

使用 CREATE TABLE LIKE DDL 陳述式重新建立目的地資料表,使其物理結構定義表示法與來源資料表的結構定義相符,然後複製或插入資料:

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`;

更改下列內容:

  • PROJECT_ID:資料表所在專案的 ID。
  • DATASET:資料表所在資料集的名稱。
  • DESTINATION_TABLE:要重新建立的目的地資料表名稱。
  • SOURCE_TABLE:來源資料表的名稱。

排解結構定義、檔案和常式巢狀結構限制錯誤

BigQuery 規定 STRUCT (RECORD) 資料欄、結構化載入檔案、巢狀常式引數和傳回類型的巢狀深度上限為 15 層。如果超出 15 層限制,系統會傳回 HTTP 400 Bad Request 錯誤,並顯示下列其中一則訊息 (其中 MAX_DEPTH 和 MAX_LEVEL 為 15)。如果錯誤是因為邏輯檢視表或 persistent user-defined function (UDF) 超出 16 層巢狀結構限制所致,請參閱「巢狀檢視表或 persistent user-defined function 數量過多」。

錯誤訊息

  • 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

診斷

STRUCT (RECORD) 類型的資料欄可包含巢狀 RECORD 欄位,最大深度為 15 層,無論欄位是純量 (NULLABLE 或 REQUIRED) 還是陣列 (REPEATED) 都是如此。同樣地,JSON、Parquet 和 Avro 載入工作和外部資料表在剖析巢狀結構時,也會強制執行巢狀結構限制。如果是 Parquet 檔案,限制會以最大定義層級和最大重複層級表示。

在常式錯誤中,TYPE_DESCRIPTION 會識別巢狀類型:argument type、return type 或 return table type。

解析度

這項上限無法提高。如要解決這個錯誤,請執行下列任一操作:

  • 扁平化結構定義或常式類型定義。將資料表架構或常式引數和傳回類型中深度巢狀的 STRUCT 或 ARRAY 階層,拆分為個別的相關資料表,並在查詢時彙整,或將深度巢狀的屬性升級為較高層級的資料欄。
  • 使用內建的 JSON 資料類型。如果資料需要超過 15 層巢狀結構,請將深度巢狀子樹儲存在 JSON (或 STRING) 類型的資料欄中。JSON 資料欄會儲存為資料表結構定義中的單一資料欄,避免 15 層 RECORD 結構定義限制,同時仍可讓您在查詢時使用 JSON 欄位存取運算子和函式擷取深度巢狀路徑。
  • 載入前預先處理輸入檔案。如果是在從 Cloud Storage 中的 JSON、Parquet 或 Avro 檔案載入工作期間發生錯誤,請新增上游預先處理步驟,將超過 15 層的結構扁平化或序列化,再載入 BigQuery。