G-gen の杉村です。BigQuery では、Cloud Storage 上の CSV 形式や JSON 形式のファイルをテーブルに読み込ん(ロード)だり、外部テーブル定義によって直接クエリすることができます。日付を含むファイルをロードしたりクエリしようとした際に発生したエラーについて、対処法を解説します。
前提
Cloud Storage バケットに以下の CSV を配置し、BigQuery から LOAD ステートメントを実行して、テーブルに取り込もうとしました。
2025/06/07,2025/06/07 08:30:00,2025/06/07 17:30:00,helloWorld1 2025/06/08,2025/06/08 09:00:00,2025/06/08 17:30:00,helloWorld2 2025/06/09,2025/06/09 10:00:30,2025/06/09 19:00:30,helloWorld3
なおテーブルのスキーマは CSV のフィールドどおりの順番で、以下を想定しています。
列名 | 型 |
---|---|
col_date | DATE |
col_datatime | DATETIME |
col_timestamp | TIMESTAMP |
col_string | STRING |
また別の用途のため、上記のテーブルとは別に、同じファイルに対して外部テーブル定義をして、直接ファイルをクエリできるようにしたいと考えています。
事象
1. LOAD の際のエラー
Cloud Storage バケット上の CSV ファイルを BigQuery テーブルに取り込むため、以下の LOAD 文を実行しました。
LOAD DATA INTO `my-project.my_dataset.sample_table` ( col_date DATE, col_datetime DATETIME, col_timestamp TIMESTAMP, col_string STRING ) FROM FILES ( format = 'CSV', uris = ['gs://my-bucket/datetime_test/test_dateformat.csv'] );
すると、以下のエラーが発生しました。
Error while reading data, error message: Unable to parse; line_number: 1 byte_offset_to_start_of_line: 0 column_index: 0 column_name: "col_date" column_type: DATE value: "2025/06/07" File: gs://my-bucket/datetime_test/test_dateformat.csv

2. 外部テーブルへのクエリの際のエラー
次に、CREATE EXTERNAL TABLE 文で同じファイルに対して外部テーブル定義を試みました。
CREATE OR REPLACE EXTERNAL TABLE `my-project.my_dataset.sample_external_table` ( col_date DATE, col_datetime DATETIME, col_timestamp TIMESTAMP, col_string STRING ) OPTIONS ( format = 'CSV', uris = ['gs://my-bucket/datetime_test/test_dateformat.csv'] );
外部テーブル作成は成功しましたが、この外部テーブルに SELECT 文を実行した際に以下のエラーメッセージが表示されました。
Error while reading table: my-project.my_dataset.sample_external_table, error message: Unable to parse; line_number: 1 byte_offset_to_start_of_line: 0 column_index: 0 column_name: "col_date" column_type: DATE value: "2025/06/07" File: gs://my-bucket/datetime_test/test_dateformat.csv

原因
BigQuery の DATE 型や DATETIME 型、TIMESTAMP 型では、文字列をキャストする際に、日付部分が YYYY-mm-dd
というハイフン区切りの形式であれば自動的に日付として認識されます。
今回は、CSV ファイル内の文字列の日付部分が、「2025/06/07」とスラッシュ区切りのため上記の形式に一致しておらず、LOAD に失敗したり、外部テーブルとしてのクエリが失敗しました。
対処法
1. date_format オプションを指定する
以下に紹介する date_format
オプション、datetime_format
オプション、time_zone
オプション等は2025年6月現在、Preview 段階です。本番環境への採用は推奨されていませんので、慎重にご検討ください。しかしながら、最もスマートで直接的な方法であるため、一番目に紹介しています。
LOAD や CREATE TABLE 文において、date_format
オプション、datetime_format
オプションを使うことで、日付にパースする文字列のフォーマットを指定することができます。以下は、その例です。
LOAD DATA INTO `my-project.my_dataset.sample_table` ( col_date DATE, col_datetime DATETIME, col_timestamp TIMESTAMP, col_string STRING ) FROM FILES ( format = 'CSV', uris = ['gs://my-bucket/datetime_test/test_dateformat.csv'], time_zone = "Asia/Tokyo", date_format = 'YYYY/MM/DD', datetime_format = 'YYYY/MM/DD HH24:MI:SS' );
なお上記の例では、time_zone
オプションでタイムゾーンを指定することで、タイムゾーンを意識する TIMESTAMP 型の列に、任意のタイムゾーンで値を格納しています。
クエリ
SELECT * FROM `my-project.my_dataset.sample_table`;
クエリの結果
col_date | col_datetime | col_timestamp | col_string |
---|---|---|---|
2025-06-07 | 2025-06-07T08:30:00 | 2025-06-07 08:30:00 UTC | helloWorld1 |
2025-06-08 | 2025-06-08T09:00:00 | 2025-06-08 08:30:00 UTC | helloWorld2 |
2025-06-09 | 2025-06-09T10:00:30 | 2025-06-09 10:00:30 UTC | helloWorld3 |
上記の結果では、2025/06/07 17:30:00
という日本時間の時刻を格納した文字列が、col_timestamp 列に 2025-06-07 08:30:00 UTC
として正しく格納されていることがわかります。
また、CREATE EXTERNAL TABLE でも、同じように date_format
オプション、datetime_format
オプションが使えます。time_zone
オプションも解釈され、外部テーブルへのクエリ時に正しくタイムゾーンが設定されます。
CREATE OR REPLACE EXTERNAL TABLE `my-project.my_dataset.sample_external_table` ( col_date DATE, col_datetime DATETIME, col_timestamp TIMESTAMP, col_string STRING ) OPTIONS ( format = 'CSV', uris = ['gs://my-bucket/datetime_test/test_dateformat.csv'], time_zone = "Asia/Tokyo", date_format = 'YYYY/MM/DD', datetime_format = 'YYYY/MM/DD HH24:MI:SS' );
他に、時刻のフォーマットを指定する time_format
オプションや、タイムスタンプのフォーマットを指定する timestamp_format
オプションもあります。
2. STRING 型として取り込む
CSV の文字列を、いったん STRING 型の文字列として取り込み、後から ELT(データ変換)やビューで任意の型に変換することができます。
LOAD DATA INTO `my-project.my_dataset.sample_table` ( col_date STRING, col_datetime STRING, col_timestamp STRING, col_string STRING ) FROM FILES ( format = 'CSV', uris = ['gs://my-bucket/datetime_test/test_dateformat.csv'] );
また、外部テーブルの場合は以下のようになります。
CREATE OR REPLACE EXTERNAL TABLE `my-project.my_dataset.sample_external_table` ( col_date STRING, col_datetime STRING, col_timestamp STRING, col_string STRING ) OPTIONS ( format = 'CSV', uris = ['gs://my-bucket/datetime_test/test_dateformat.csv'] );
このようにしてできたテーブルや外部テーブルに対して、以下のように PARSE_*
関数を使ってクエリすることで、文字列を日付型等に変換することができます。
SELECT PARSE_DATE("%Y/%m/%d", col_date) AS col_date, PARSE_DATETIME("%Y/%m/%d %H:%M:%S", col_datetime) AS col_datetime, PARSE_TIMESTAMP("%Y/%m/%d %H:%M:%S", col_timestamp, "Asia/Tokyo") AS col_timestamp, col_string, FROM `my-project.my_dataset.sample_table`
- 参考 : Date functions
- 参考 : Datetime functions
- 参考 : Timestamp functions
3. スキーマの自動検知を利用する
以下のようにスキーマ(列名、型)を指定せずに LOAD すると、スキーマが自動判断されてロードされます。スラッシュ区切りの日付文字列も、DATE 型等として判断されます。
LOAD DATA INTO `my-project.my_dataset.sample_table_auto` FROM FILES ( format = 'CSV', uris = ['gs://my-bucket/datetime_test/test_dateformat.csv'] );
外部テーブル定義の場合は、以下のようになります。
CREATE OR REPLACE EXTERNAL TABLE `my-project.my_dataset.sample_external_table` OPTIONS ( format = 'CSV', uris = ['gs://my-bucket/datetime_test/test_dateformat.csv'] );
この方法だと、列名や型を指定することができません。上記の方法で作成されたテーブルや外部テーブルを SELECT すると、いずれも以下のような結果となりました。
date_field_0 | timestamp_field_1 | timestamp_field_2 | string_field_3 |
---|---|---|---|
2025-06-07 | 2025-06-07 08:30:00 UTC | 2025-06-07 17:30:00 UTC | helloWorld1 |
2025-06-08 | 2025-06-08 09:00:00 UTC | 2025-06-08 17:30:00 UTC | helloWorld2 |
2025-06-09 | 2025-06-09 10:00:30 UTC | 2025-06-09 19:00:30 UTC | helloWorld3 |
CSV の2列目と3列目のフィールドはいずれも TIMESTAMP 型として解釈され、タイムゾーンは UTC として解釈されました。
この方法では任意の列名や型を指定できない点に留意が必要です。
4. 取り込む前にファイルを前処理する
上記の方法のほか、BigQuery からファイルを読み込む前の前処理として、ファイル自体を加工する(ELT ではなく ETL)という方法も検討できます。
この場合は BigQuery の機能だけでは取り込みを完結できません。ファイルの前処理のためのアーキテクチャを検討する必要があります。
杉村 勇馬 (記事一覧)
執行役員 CTO / クラウドソリューション部 部長
元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。
Follow @y_sugi_it