# Python3.7でCloud Firestoreを操作する
Google Cloudにプロジェクトを追加し、PythonのCloud Firestoreを操作するライブラリgoogle-cloud-firestore
でCloud Firestoreでのドキュメントの追加、参照、変更、削除する方法をみていく。
# Cloud Firestoreとは
Cloud Firestoreは、Cloud Datastoreの後継で、Google Cloudが提供しているフルマネージドのNoSQLだ。
# 準備
前提として、Cloud FirestoreはCloud Datastoreと同じプロジェクトで使うことができない。
Cloud Firestore and App Engine: You can't use both Cloud Firestore and Cloud Datastore in the same project, which might affect apps using App Engine. https://cloud.google.com/firestore/docs/quickstart-servers?hl=ja (opens new window)
# プロジェクトの作成
gcloud projects create プロジェクト名
でプロジェクトを作成する。
$ gcloud projects create gae-firestore-app
# gcloudコマンド実行時のプロジェクト
gcloud
のコマンド実行時はオプションなしの場合、デフォルトのプロジェクトに対して操作を行う。
gcloud
に--project=[プロジェクトID]
オプションをつけることで、デフォルトのプロジェクト以外を操作できる。
なお、デフォルトのプロジェクトは変更できるので、gcloud config set project [プロジェクトID]
で変更してもよい。その場合、gcloud
コマンド実行時に--project=[プロジェクトID]
オプションは不要になる。
$ gcloud config set project gae-firestore-app
# サービスアカウント作成
Cloud DatastoreをPythonで操作する際に、操作する権限をもっていることを示す必要があるため、キーファイルが必要になる。そのキーファイルをつくるために、サービスアカウントを作成する。
次のコマンドでサービスアカウントを作成する。
gcloud iam service-accounts create [サービスアカウント名]
$ gcloud iam service-accounts create firestore-service-account --project=gae-firestore-app
Created service account [firestore-service-account].
# サービスアカウントへ権限を付与する
次のコマンドでサービスアカウントへ権限を付与する。
gcloud projects add-iam-policy-binding [プロジェクトID] --member "serviceAccount:[サービスアカウント名]名@[プロジェクトID].iam.gserviceaccount.com" --role [ロール]
$ gcloud projects add-iam-policy-binding gae-firestore-app --member "serviceAccount:firestore-service-account@gae-firestore-app.iam.gserviceaccount.com" --role "roles/owner" --project=gae-firestore-app
Updated IAM policy for project [gae-firestore-app].
# キーファイルを生成する
次のコマンドでキーファイルを生成する。
gcloud iam service-accounts keys create [キーファイル名].json --iam-account [サービスアカウント名]@[プロジェクトID].iam.gserviceaccount.com
コマンドを実行すると、ローカルにコマンド実行時に指定したキーファイル名のJSONファイルが出来上がる。 このJSONファイルを確認すると、プロジェクトIDや秘密鍵、サービスアカウントのメールアドレスなどが格納されている。
$ gcloud iam service-accounts keys create service-account.json --iam-account firestore-service-account@gae-firestore-app.iam.gserviceaccount.com
created key [e3e79611a383c1c144cf8dee5812a0b490f5d738] of type [json] as [service-account.json] for [firestore-service-account@gae-firestore-app.iam.gserviceaccount.com]
$ ls -l service-account.json
-rw------- 1 nancy staff 2356 5 14 21:28 service-account.json
$ cat service-account.json
{
"type": "service_account",
"project_id": "gae-firestore-app",
"private_key_id": "xxx",
"private_key": "-----BEGIN PRIVATE KEY-----yyy-----END PRIVATE KEY-----\n",
"client_email": "firestore-service-account@gae-firestore-app.iam.gserviceaccount.com",
"client_id": "zzz",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firestore-service-account%40gae-firestore-app.iam.gserviceaccount.com"
}
# PythonからCloud Firestoreへ接続する
PythonからCloud Firestoreを操作できるようにするため、google-cloud-firestore
をインストールする。
$ pipenv install google-cloud-firestore==1.1.0
service-account.json
と同じ階層に、Cloud Firestoreを操作するPythonファイル(use-cloud-firestore.py
)を用意する。
firestore.Client().from_service_account_json([Cloud Firestoreへの編集権限があるキーファイル名])
を指定して、Cloud Firestoreへ接続する。
use-cloud-firestore.py
from google.cloud import firestore
db = firestore.Client().from_service_account_json('service-account.json')
print(db)
Visual Studio Codeでデバッグして動かしてみると、from_service_account_json()
メソッドで取得したオブジェクトに、Cloud Firestoreを操作できそうなものが入っていることがわかる👀
# 操作
それでは、実際にPythonからCloud Firestoreへ接続して、追加、参照、変更、削除を試していく。
# 追加
Google Cloud PlatformのコンソールでFirestoreが空であることを確認する。
db.collection(コレクションのパス).document(ドキュメントのパス)
でドキュメントへの参照を取得し、set()
メソッドでデータを追加する。
from google.cloud import firestore
db = firestore.Client().from_service_account_json('service-account.json')
doc_ref = db.collection('users').document('masaru-hanada')
doc_ref.set({
'first': 'まさる',
'last': 'はなだ',
'born': 1986
})
doc_ref = db.collection('users').document('hanako-kato')
doc_ref.set({
'first': 'はなこ',
'last': 'かとう',
'born': 1934
})
上記のPython実行後に再度コンソールを確認すると、set
した内容が表示されている。
# 参照
一覧、1件の取得それぞれを見ていく。
# 一覧の参照
コレクションのパスを指定してドキュメントの一覧を取得する方法をみていく。
CollectionReference
に対してget
しようとすると、廃止予定だからstream
を使えと表示される。
'Collection.get' is deprecated: please use 'Collection.stream' instead.
CollectionReference
に対してstream()
メソッドを使いDocument
の一覧を取得し、ループする。
各フィールドはDocumentSnapshot
に対してget(フィールド名)
で取得する。
CollectionReference
のstream()
メソッド取得できるものは、あんまり理解できてないが、ドキュメントをfor文で回せるもの、と理解しておく。
何に対して操作しているのかわかりづらかったので、下記モジュール中の変数名とオブジェクトの対比表を書いた。
下記モジュール中の変数名 | オブジェクト | 概要 |
---|---|---|
db | google.cloud.firestore_v1.client.Client (opens new window) | Google Cloudを操作するためのクライアント |
user_ref | google.cloud.firestore_v1.collection.CollectionReference (opens new window) | コレクション |
docs | generator object Query.stream(これはオブジェクトてくくりだと変かも) | ドキュメントの一覧 |
doc | google.cloud.firestore_v1.document.DocumentSnapshot (opens new window) | ドキュメントのスナップショット |
from google.cloud import firestore
db = firestore.Client().from_service_account_json('service-account.json')
user_ref = db.collection('users')
docs = user_ref.stream()
for doc in docs:
print('姓:{} 名:{} 生まれ年:{}'.format(
doc.get('last'), doc.get('first'), doc.get('born')))
# 1件の参照
ドキュメントのパスを指定して1件だけ取得する方法を見ていく。
CollectionReference
のdocument
メソッドで取得できるのはgoogle.cloud.firestore_v1.document.DocumentReference
だ。DocumentReference
に対してget()
メソッドを実行することで、DocumentSnapshot
が取得できる。
from google.cloud import firestore
db = firestore.Client().from_service_account_json('service-account.json')
user_ref = db.collection('users').document('hanako-kato')
snapshot = user_ref.get()
print(snapshot.to_dict())
# 変更
db.collection(コレクションのパス).document(ドキュメントのパス)
でドキュメントへの参照を取得し、update()
メソッドでデータを更新する。
from google.cloud import firestore
db = firestore.Client().from_service_account_json('service-account.json')
user_ref = db.collection('users').document('hanako-kato')
user_ref.update({'born': 1990})
# 削除
db.collection(コレクションのパス).document(ドキュメントのパス)
でドキュメントへの参照を取得し、delete()
メソッドでドキュメントを削除できる。
from google.cloud import firestore
db = firestore.Client().from_service_account_json('service-account.json')
user_ref = db.collection('users').document('hanako-kato')
user_ref.delete()
・参考
https://cloud.google.com/firestore/?hl=ja (opens new window)
https://cloud.google.com/firestore/docs/quickstart-servers (opens new window)
https://github.com/GoogleCloudPlatform/python-docs-samples/blob/b20c339fadd62543bc74ce7fe07ded47c6e6c6c0/firestore/cloud-client/snippets.py#L36-L41 (opens new window)
https://googleapis.github.io/google-cloud-python/latest/firestore/index.html (opens new window)
https://github.com/googleapis/google-cloud-python/tree/master/firestore (opens new window)