【Python】BigQueryのテーブル/テーブルスキーマを取得する方法

本記事ではPythonを使用した以下の操作を解説しています.

  • BigQueryからテーブルをpandas DataFrameとして取得する
  • テーブルのスキーマに関する情報を取得する

前提条件

本記事ではPythonのBigQuery APIクライアントライブラリを使用します.
インストールをしていない場合は先にインストールが必要です.

  • 検証バージョン:google-cloud-bigquery 3.4.0

BigQueryからテーブルを取得する

BigQuery上にあるテーブルをSQLクエリで取得します.


from google.cloud import bigquery

# BigQueryのパブリックデータ(67.58 KB)
query = '''
SELECT
    County_of_Residence,
    Births,
    Ave_Age_of_Mother
FROM
    `bigquery-public-data.sdoh_cdc_wonder_natality.county_natality`
LIMIT
    10
'''

client = bigquery.Client()
cj = client.query(query)
print(cj, '\n', type(cj))
QueryJob<project=***, location=US, id=***>
 <class 'google.cloud.bigquery.job.query.QueryJob'>

BigQueryからのテーブル取得はClient()オブジェクトのメソッドquery()で可能です.
query()を実行するとQueryJobオブジェクトが返ってきます.

注意

BigQueryは実行した操作に応じて料金がかかるため,クエリを変更する際などは注意してください.1

QueryJobオブジェクトには様々なメソッドがありto_dataframe()メソッドを使用すれば取得したテーブルをDataFrameとして取得できます.


df = cj.to_dataframe()
df.head(3)
County_of_Residence Births Ave_Age_of_Mother
0 Calhoun County, AL 1265 26.67
1 Tulsa County, OK 8933 28.13
2 Carroll County, GA 1540 27.20

to_dataframe()メソッドの主な引数は以下のとおりです.

引数 説明
bqstorage_client BigQuery Storage API client を使用して結果を高速に取得できる
dtypes DataFrameの列におけるデータ型を指定
progress_bar_type tqdm packageのプログレスバーを表示できる
max_results 取得する結果の最大行数を指定

以下はdtypesprogress_bar_typeを指定して実行した例です.


dtypes={'Births': 'float16'}

df = cj.to_dataframe(dtypes=dtypes, progress_bar_type='tqdm')
df.dtypes
Job ID *** successfully executed: 100%|██████████|
Downloading: 100%|██████████|

County_of_Residence     object
Births                 float16
Ave_Age_of_Mother      float64
dtype: object

DataFrameのデータ型を見ると指定した「Births」列がfloat16になっていますね.
またprogress_bar_typeを指定しているので,進捗具合も表示されています.

高速化に関して(クリックで展開します)

bqstorage_clientにBigQuery Storage API clientを指定すると高速にテーブルを取得できると公式ドキュメントに記載がありますが,管理人の手元では指定の有無に関わらず取得速度に差がありませんでした.
取得するデータが大きい場合などでは効果があるかもしれません.
(こうしたら早くなるなど,情報をお持ちの方がいらっしゃればご連絡いただけると嬉しいです.問い合わせフォーム or Twitter

なお,以下「関連記事」で紹介しているpandasのread_gbqメソッドについては引数use_bqstorage_api=Trueとするとテーブルの取得を圧倒的に高速化できます.

関連記事

BigQueryからテーブルをDataFrameとして取得するにはpandasのread_gbqメソッドを使う方法もあります.
テーブルデータをDataFrameとして扱いたい場合はこちらの方がシンプルで便利です.

テーブルのスキーマに関する情報を取得する

スキーマの情報を取得する例を以下より確認していきます.

QueryJobオブジェクトのresult()メソッドでRowIteratorオブジェクトを取得します.


cjr = cj.result()
cjr
<google.cloud.bigquery.table.RowIterator at ***>

スキーマ

テーブルのスキーマを確認するにはschema属性を使用します.


cjr.schema
[SchemaField('County_of_Residence', 'STRING', 'NULLABLE', None, None, (), None),
 SchemaField('Births', 'INTEGER', 'NULLABLE', None, None, (), None),
 SchemaField('Ave_Age_of_Mother', 'FLOAT', 'NULLABLE', None, None, (), None)]

schema属性にはSchemaFieldというオブジェクトがリストで存在し,それぞれのSchemaFieldが各列(カラム)ごとの情報を保持しています.必要な情報にはSchemaFieldの属性を使用してアクセスします.

列名(カラム名,フィールド名)

列名はSchemaFieldのname属性で取得します.
以下の例では全カラム名をfor文で取り出しています.


[i.name for i in cjr.schema]
['County_of_Residence', 'Births', 'Ave_Age_of_Mother']

列のデータ型(フィールドタイプ)

各列のデータ型はfield_type属性で取得します.


[i.field_type for i in cjr.schema]
['STRING', 'INTEGER', 'FLOAT']

列名,データ型,モードを辞書で取得

SchemaFieldのto_api_repr()メソッドを使用すればスキーマの情報を辞書で取得できます.


[i.to_api_repr() for i in cjr.schema]
[{'name': 'County_of_Residence', 'type': 'STRING', 'mode': 'NULLABLE'},
 {'name': 'Births', 'type': 'INTEGER', 'mode': 'NULLABLE'},
 {'name': 'Ave_Age_of_Mother', 'type': 'FLOAT', 'mode': 'NULLABLE'}]

行数

行数はRowIteratorオブジェクトのtotal_rows属性で確認できます.


cjr.total_rows
10

その他の属性

他にもスキーマに関する主な情報は以下の属性で取得できます.

属性 取得できる情報
mode モード
is_nullable モードがNULLABLEか否か
default_value_expression デフォルト値
policy_tags ポリシータグ
description 説明

参考

その他の属性や詳細は以下の公式 Referenceを参照.

関連情報

BigQuery INFORMATION_SCHEMAを使用して情報を取得することも可能です. クエリでテーブル情報を取得できるのでとても便利です.

ひとこと

BigQuery APIクライアントライブラリを使うとPythonで色々な情報を取得できますね.
テーブルを取得するだけならpandasのread_gbqをよく使います.


  1. 上記のサンプルコード(クエリ)の処理量は約68KBと少ないのでそれほど気にする必要はありません.