スキーマエラーのトラブルシューティング
このドキュメントは、BigQuery テーブル スキーマを変更するとき、または深くネストされたスキーマ構造を定義または読み込むときに発生する HTTP 400 Bad Request エラーを診断して解決するのに役立ちます。INFORMATION_SCHEMA ビューを使用して BigQuery のパフォーマンスをトラブルシューティングする方法については、情報スキーマを使用したトラブルシューティングをご覧ください。
スキーマの不一致エラーのトラブルシューティング
次のいずれかのオペレーションで、ターゲット テーブルの既存のスキーマと競合するスキーマが指定されると、BigQuery は Provided Schema does not match Table エラー(reason: invalid)を返します。
- 読み込みジョブ
- 宛先テーブルを含むクエリジョブ
- コピージョブ
ALTER TABLEDDL ステートメント- テーブル メタデータの更新(
tables.updateまたはtables.patch)
具体的な原因と解決策を特定するには、エラー メッセージを次のいずれかのシナリオに一致させます。
新しいスキーマにフィールドがありません
エラー メッセージ
Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Field FIELD_NAME is missing in new schema
診断
次のいずれかのオペレーションで、宛先テーブルにすでに存在する 1 つ以上の列を省略したスキーマ定義を指定します。
- 読み込みジョブ
- DataFrame の書き込みオペレーション
tables.updateまたはtables.patchAPI 呼び出し
解決策
BigQuery では、API スキーマ ペイロードまたは読み込みジョブ構成から列を省略して、暗黙的に列を削除することはできません。このエラーを解決するには、以下のいずれかを行います。
- 指定されたスキーマにターゲット テーブルの既存の列がすべて含まれるように、パイプラインまたは API リクエストを更新します。
テーブルから列を削除する場合は、読み込みリクエストまたはパッチ リクエストから列を省略するのではなく、
DROP COLUMNDDL ステートメントを実行します。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 COLUMNDDL ステートメントを使用します。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 への変更など)が試行されています。このエラーは、REPEATED 列を含むテーブルの REQUIRED 列を緩和するときに、bq コマンドライン ツールでインライン スキーマ定義を使用した場合にも発生します。これは、bq コマンドライン ツールのインライン スキーマ定義では、REPEATED 列を含むテーブルの変更がサポートされていないためです。
解決策
BigQuery スキーマのインプレース更新でサポートされているモード変更は、列のモードを REQUIRED から NULLABLE に緩和することのみです。このエラーを解決するには、以下のいずれかを行います。
- 列を
REQUIREDからNULLABLEに緩和する場合は、GoogleSQL でALTER TABLE ... ALTER COLUMN ... DROP NOT NULLDDL ステートメントを実行します。bq updateコマンドまたはtables.patchAPI メソッドを使用してスキーマを更新する場合は、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 列の直接追加を拒否します。
解決策
このエラーを解決するには、以下のいずれかを行います。
REQUIREDではなくモードNULLABLEで新しい列を追加し、DMLUPDATEステートメントを実行して既存の行に値を入力します。列を追加してデフォルト値を割り当てるには、次の操作を行います。
- 列を
NULLABLE列として追加します。 - 列のデフォルト値を設定して、今後の挿入で値が自動的に受信されるようにします。
既存の行を更新してデフォルト値を入力します。
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 を指定しながら、既存のテーブルに新しい列を追加しようとしています。1 回の 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ステートメントのみを実行します。
既存の ID 列の属性の更新はサポートされていません
エラー メッセージ
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 パッチを介して、既存の ID 列の属性を変更しようとしています。
解決策
ID 列のプロパティは、作成後にインプレースで変更できません。スキーマ更新ペイロードで既存の ID 列定義を変更しないようにするか、更新された ID 列構成で新しいテーブルを作成し、新しいテーブルにデータをコピーまたは読み込みます。手順については、テーブル スキーマの変更をご覧ください。
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 型を列の既存のスキーマと比較し、次のいずれかを行います。
- 同じサブフィールドを同じ順序で保持し、列のデータ型の変更でサポートされている方法でのみサブフィールドの型を変更します。
- DDL では、ネストされたサブフィールドを既存の
RECORD列に追加できません。代わりに、bq updateまたはtables.patchメソッドで JSON スキーマ ファイルを使用してスキーマを更新します。詳細については、ネストされた列をRECORD列に追加するをご覧ください。 - ネストされたサブフィールドを削除または再構築するには、ネストされた列の型を変更するをご覧ください。
分岐する物理スキーマの最大数に達しました
エラー メッセージ
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)。論理ビューまたは永続的なユーザー定義関数(UDF)で 16 レベルのネストの上限を超えたことによるエラーについては、ネストされたビューまたは永続的なユーザー定義関数が多すぎるをご覧ください。
エラー メッセージ
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)型の列には、フィールドがスカラー(NULLABLE または REQUIRED)か配列ベース(REPEATED)かに関係なく、最大 15 レベルの深さまでネストされた RECORD フィールドを含めることができます。同様に、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 に読み込みます。