Python 版 の Firestore クライアントを使ってみよう
Firestore の操作は cloud functions や firebase-admin などの js 系のクライアントからが一般的だと思いますが、データメンテなどで単発のバッチ系作業をするのに Jupyter notebook からPython使うとめっちゃ楽ちんなのです!
そして意外と本家 Firebase のヘルプサイトからのナビゲーションが悪いので Python 版 Firestore クライアントのヘルプに辿り着くのが難易度高いのです。
早速ですが以下が Python 版 Firebase クライアントのドキュメントです。
いや~本家のヘルプサイトにはサクッとしか使い方載ってないので上記のドキュメントに辿り着くのにまたググらないといけないのがアレですね。。。
それでは早速、準備に取り掛かりましょう。
サービスアカウントの準備
まず、firestore 編集者
の権限をもったサービスアカウントの認証キー json をダウンロードしておきましょう。
それを適当な場所に配置しておきます。
準備が整いましたら notebook から叩いてみたいと思います。
Python クライアントのインストール
今回は jupyter notebookから!pip
でインストールしてみます!
!pip install google-cloud-firestore
クライアントのインストールはこれだけでOKです!
とりあえずデータを取得
実際、あっけないほどシンプルではございますが、以下のようなコードでシンプルにデータ取得できます。
from google.cloud import firestore
service_account_json = '/path/to/service_account.json'
client = firestore.Client.from_service_account_json(service_account_json)
mycollection = client.collection('Sample_Collection')
# 全件
for mycol in mycollection.stream():
item = mycol.to_dict()
...
# 500件
for mycol in mycollection.limit(500).stream():
item = mycol.to_dict()
...
# 検索条件付きで 500件
for mycol in mycollection.select('target','=','0').limit(500).stream():
item = mycol.to_dict()
...
# 検索条件とソート付きで 500件
for mycol in mycollection.select('target','=','0').order_by('name').limit(500).stream():
item = mycol.to_dict()
...
サービスアカウントのjsonを渡せばもうクライアントの接続準備完了です。
後は好きなコレクションをstream()
で取得してto_dic()
してしまえばデータの加工も問題なしです。
検索条件やソートについてはあらかじめインデクスの設定が必要です。
offset
やstart_after
などを組み合わせればページングもできます。
このあたりの詳しい操作は公式ガイドにも載っていますね。
データの保存
続いて書き込みですが・・・
mycollection = client.collection('Sample_Collection')
target = client.collection('Target_Collection')
# IDを自動生成で追加
for mycol in mycollection.stream():
target.add(mycol.to_dict())
# IDを指定して
for mycol in mycollection.stream():
item = mycol.to_dict()
target.document(mycol.id).set(item)
# 既知のIDを指定して特定のフィールドをアップデート
for mycol in mycollection.stream():
item = mycol.to_dict()
target.document(item['name']).update({'updateDate': firestore.SERVER_TIMESTAMP})
なにが素晴らしいって、dict
をそのまま add
やら set
でデータ突っ込んでOKということです。
dict
の値は Python の型でOKですので True
とか datetime
も宜しく変換してくれます。
firebase のプロジェクトをまたいだデータ投入
サービスアカウントjson
で接続していますので、ステージングから本番にデータを移行とかデータのバックアップなどのプロジェクトをまたいだデータ操作も以下のようにお手軽です。
from google.cloud import firestore
staging_sa_json = '/path/to/staging/service_account.json'
prod_sa_json = '/path/to/prod/service_account.json'
stagingProj = firestore.Client.from_service_account_json(staging_sa_json)
prodProj = firestore.Client.from_service_account_json(prod_sa_json)
stagingCollection = stagingProj.collection('Sample_Collection')
prodCollection = prodProj.collection('Sample_Collection')
for mycol in stagingCollection.stream():
item = mycol.to_dict()
prodCollection.document(mycol.id).set(item)
上記でIDそのままで全データがコピーできます。
また、firestore のドキュメントはかなり複雑な階層も作れます。
dict
でどうやって指定しよう?というときは以下の FieldPath を使うことになるかと思います。
.
(ピリオド)区切りの名前でだいたい大丈夫な模様です。
Python からのデータ操作、非常に簡単です。
いやぁ、ちょっとデータ取ってきたりごにょごにょするには非常に便利ですね~!
料金に注意!
ただし、クライアントの操作なので読み込みと書き込みでしっかり課金されます。。。。
ご利用は計画的に!