この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、みかみです。
ついにきました!
INFORMATION_SCHEMA
の TABLES
ビューから、既存テーブルの CREATE TABLE
文が取得できるようになりました!
何がうれしいの?
システムで使用しているデータベースのテーブル定義は CREATE TABLE
構文で SQL ファイルに記載して、コード管理するのが一般的ではないかと思います。
BigQuery の既存テーブルのテーブル定義は、これまでも JSON 形式では取得することができましたが、CREATE TABLE
構文の SQL として欲しい場合、手動で作成する必要がありました。
「テーブルにデータ入れるなら、どうせ初めに手動でテーブル作成しないといけないんじゃないの?」と思われるかもしれんせんが、BigQuery では CSV などのファイルからフォーマットを自動検出してデータをロードする時に自動でテーブルを作成することも可能です。
自動作成ではテーブルやカラムの論理名の付与やパーティショニングなどはしてくれないので、実際にシステムで利用するテーブルは作成しなおす必要があると思いますが、カラムの物理名やデータ型が定義済みのベースとなるテーブル定義が SQL で取得できれば、テーブルを作成&管理するのがだいぶ楽になるのです。
ということで、2021/04/07 現在まだプレビューですが、INFORMATION_SCHEMA
から DDL が取得できるようになったこの BigQuery のアップデート、待ってました!v
JSON 形式のテーブル定義を取得
論理名やパーティショニング、クラスタリングや有効期限などの設定された、以下のテーブルのスキーマ情報を取得してみます。
JSON 形式のテーブルスキーマの情報は、bq show --schema
コマンドで取得することができます。
Cloud Shell から以下のコマンドで、テーブルスキーマを JSON ファイルに出力しました。
bq show --schema --format=prettyjson dataset_1.table_A1_cp > schema_table_A1_cp.json
出力した JSON ファイルの中身を見てみます。
[
{
"description": "STRING\u578b\u30ab\u30e9\u30e0",
"mode": "REQUIRED",
"name": "col_string",
"type": "STRING"
},
{
"description": "INTEGER\u578b\u30ab\u30e9\u30e0",
"mode": "REQUIRED",
"name": "col_integer",
"type": "INTEGER"
},
{
"description": "DATE\u578b\u30ab\u30e9\u30e0",
"name": "col_date",
"type": "DATE"
},
{
"description": "DATETIME\u578b\u30ab\u30e9\u30e0",
"name": "col_datetime",
"type": "DATETIME"
},
{
"description": "TIMESTAMP\u578b\u30ab\u30e9\u30e0",
"name": "col_timestamp",
"type": "TIMESTAMP"
},
{
"description": "RECORD\u578b\u30ab\u30e9\u30e0",
"fields": [
{
"description": "\u30ec\u30b3\u30fc\u30c9A",
"mode": "REPEATED",
"name": "a",
"type": "STRING"
},
{
"description": "\u30ec\u30b3\u30fc\u30c9B",
"name": "b",
"type": "BOOLEAN"
}
],
"name": "col_record",
"type": "RECORD"
}
]
カラムの物理名やデータ型、NOT NULL 制約の情報は取得できましたが、論理名はユニコードになっているので、 標準 SQL のテーブル定義に慣れていると、可読性は良くありません。。
また、パーティショニングやクラスタリング、有効期限などその他のテーブル情報は、別途 bq show
コマンドでテーブル名を指定して確認する必要があります。
mikami_yuki@cloudshell:~ (cm-da-mikami-yuki-258308)$ bq show dataset_1.table_A1_cp
Table cm-da-mikami-yuki-258308:dataset_1.table_A1_cp
Last modified Schema Total Rows Total Bytes Expiration Time Partitioning Clustered Fields Labels
----------------- ------------------------------------ ------------ ------------- ----------------- -------------------------------------------------------- ------------------------- ----------------
07 Apr 09:26:16 |- col_string: string (required) 0 0 31 Dec 14:59:59 MONTH (field: col_timestamp, expirationMs: 7776000000) col_string, col_integer type:partition
|- col_integer: integer (required) sample:table_a
|- col_date: date
|- col_datetime: datetime
|- col_timestamp: timestamp
+- col_record: record
| |- a: string (repeated)
| |- b: boolean
やはり、テーブル定義をコード管理する場合、このままのテーブル情報だと扱いにくそうです。。。
INFORMATION_SCHEMA から SQL のテーブル定義を取得
同じテーブルのテーブル定義を、INFORMATION_SCHEMA
から取得してみます!
※2021/04/07 現在、日本語の INFORMATION_SCHEMA.TABLES
ビューのドキュメントには、まだ DDL
カラムの記載はありませんでした。
BigQuery 管理コンソールのクエリエディタから、以下の SQL を実行しました。
SELECT
table_name, ddl
FROM
`cm-da-mikami-yuki-258308`.dataset_1.INFORMATION_SCHEMA.TABLES
WHERE
table_name = 'table_A1_cp'
;
取得した DDL は以下です。
CREATE TABLE `cm-da-mikami-yuki-258308.dataset_1.table_A1_cp`
(
col_string STRING NOT NULL OPTIONS(description="STRING型カラム"),
col_integer INT64 NOT NULL OPTIONS(description="INTEGER型カラム"),
col_date DATE OPTIONS(description="DATE型カラム"),
col_datetime DATETIME OPTIONS(description="DATETIME型カラム"),
col_timestamp TIMESTAMP OPTIONS(description="TIMESTAMP型カラム"),
col_record STRUCT<a ARRAY<STRING> OPTIONS(description="レコードA"), b BOOL OPTIONS(description="レコードB")> OPTIONS(description="RECORD型カラム")
)
PARTITION BY TIMESTAMP_TRUNC(col_timestamp, MONTH)
CLUSTER BY col_string, col_integer
OPTIONS(
partition_expiration_days=90.0,
expiration_timestamp=TIMESTAMP "2021-12-31T14:59:59.000Z",
description="table_Aから作成",
labels=[("sample", "table_a"), ("type", "partition")]
);
カラムの物理名や論理名、データ型や NOT NULL 定義はもちろん、パーティショニングやクラスタリング、データの有効期限やラベル情報など、SQL でテーブル定義を取得することができました!
これならこのままコードとして管理できますし、既存テーブルの一部を変更して新しいテーブルを作成する場合や、CREATE TABLE
構文でパーティショニング定義する場合どう書くんだっけ? な時にも参照できるので便利です!
なお、カラム名を指定せず SELECT *
で参照すると、ddl
カラム値は取得できませんでした。
また、GCS に配置したファイルなどの外部データを参照する外部テーブルの DDL は、やはり取得できませんでした。
INFORMATION_SCHEMA
の TABLES
では、テーブルだけでなくビューの情報も参照できます。
確認したところ、ビューの場合にも TABLES.DDL
カラムで CREATE VIEW
文が参照できました。
これでテーブルやビューの管理がずいぶん楽になりますv
まとめ(所感)
既存テーブルの DDL を取得できるようになった今回のアップデート、きましたねv
標準 SQL に対応しているとはいえ、一部利用できない SQL 構文もあり、bq
コマンドと併用しないと若干使いにくい感が否めなかった BigQuery ですが、
ここのところ ALTER
構文などの標準 SQL 関連のアップデートも続いており、ユーザーとしてはうれしい限りです!
今後もさらなるアップデートに期待してます!