データベースに「保存」を行った日時を記録するフィールドを使って、差分更新を行う。 データベースの丸ごとのダウンロードではないので、通信量の節約などができる.
git の URL: https://git-scm.com/
git の URL: https://git-scm.com/手順は、
別ページで説明
Python のプログラム作成には,開発環境や Python コンソール(Jupyter Qt Console,Spyder,PyCharm,PyScripter など)が便利.
以下,Windows でインストール済みであるものとして説明を続ける.
pip install -U firebase-admin
※ 以上の手順は、「Python で Google Firebase の Cloud Firestore (クラウド・ファイアストア)を使ってみる」で説明している.
datetime 型の created_at フィールドを含むようなドキュメントを作る
さて、「created_at」は、ドキュメントがデータベースに挿入された日時という意味。 あとから入ったドキュメントは、前に入ったドキュメントの「created_at」よりも新しい日時の値を持つ。
例えば、次のように。
「H:/my-project-abcde-firebase-adminsdk-q53ez-5d420dbcf2.json」のところは、先ほどダウンロードした JSON ファイル名にすること。
「u'time', u'>', datetime(2019,4,13,3,10,0)」は、日時(Python の datetime) の比較
import datetime import firebase_admin from firebase_admin import credentials from firebase_admin import firestore cred = credentials.Certificate('H:/my-project-abcde-firebase-adminsdk-q53ez-5d420dbcf2.json') app = firebase_admin.initialize_app(cred) db = firestore.client() ref = db.collection(u'docs') a = ref.where(u'created_at', u'>', datetime.datetime(2019,4,8,9,30,0)) docs = a.stream() for doc in docs: print(u'{} => {}'.format(doc.id, doc.to_dict()))
import datetime import firebase_admin from firebase_admin import credentials from firebase_admin import firestore cred = credentials.Certificate('H:/my-project-abcde-firebase-adminsdk-q53ez-5d420dbcf2.json') app = firebase_admin.initialize_app(cred) db = firestore.client() ref = db.collection(u'docs') # last を設定、「created_at」の値が「last」以降のものをダウンロード last = datetime.datetime(2019,4,8,0,30,0, 0,datetime.timezone.utc) a = ref.where(u'created_at', u'>', last) docs = a.stream() new_last = last for doc in docs: print(u'{} => {}'.format(doc.id, doc.to_dict())) # 確認のため「last以降のデータであるかを表示」 print(last < doc.to_dict()['created_at']) # その中の created_at で最も最新のものを調べる if ( new_last < doc.to_dict()['created_at'] ): new_last = doc.to_dict()['created_at']
タイマーは「5」秒に設定。5秒ごとにダウンロードして、表示を繰り返す
ダウンロードのたびに、まるごとダウンロードはしたくない。差分(新しいデータ)のみをダウンロードして、すでにダウンロード済みのデータに付け加える(更新)の操作としたい。
そこで、ダウンロードごとに、ダウンロードしたドキュメントの中の「created_at で最も最新のもの」を調べる。 そして、その次のダウンロードでは、「created_at で最も最新のもの」引く10秒以降のものをダウンロードする (「10」と決めているのに、特に根拠はない. create_at を付けるシステムの側で -10秒の変動はありえるかも、と勝手に決めているだけ)
【サイト内の関連ページ】 一定間隔で処理の繰り返し
import time import threading import datetime import firebase_admin from firebase_admin import credentials from firebase_admin import firestore cred = credentials.Certificate('H:/my-project-abcde-firebase-adminsdk-q53ez-5d420dbcf2.json') app = firebase_admin.initialize_app(cred) db = firestore.client() ref = db.collection(u'docs') # base を設定、「created_at」の値が「base」以降のものをダウンロード base = datetime.datetime(2019,4,8,0,30,0, 0,datetime.timezone.utc) last = base # ダウンロードしたデータを置くためののオブジェクト。最初は空 cache = {} def worker(): global last global cache a = ref.where(u'created_at', u'>', last) docs = a.stream() new_last = last for doc in docs: # print(u'{} => {}'.format(doc.id, doc.to_dict())) # 確認のため「last以降のデータであるかを表示」 print(last < doc.to_dict()['created_at']) # ダウンロードしたデータを保存 cache[doc.id] = doc.to_dict() # その中の created_at で最も最新のものを調べる if ( new_last < doc.to_dict()['created_at'] ): new_last = doc.to_dict()['created_at'] print("cache data") print(cache) if ( last < ( new_last - datetime.timedelta(0,10) ) ): last = new_last - datetime.timedelta(0,10) def mainloop(time_interval, f): now = time.time() while True: t = threading.Thread(target=f) t.start() t.join() wait_time = time_interval - ( (time.time() - now) % time_interval ) time.sleep(wait_time) # 5秒間隔 mainloop(5, worker)