前回までの記事では、 ML4Keiba の理想的な機能について考えた
今回は、具体的にどのようにデータを「状態」として保持するか・引き出すかを考える (まぁつまり ETL ってやつだ)
DB の選定
思えばいままでずっとデータベースと触れ合うことを避けてきた
なるべく関数志向というか、「状態」に依存しないようにコードを書き、どうしても必要なときは状態管理フレームワークでよしなにしてもらうだけだった (ちょっとズレるけども)
考慮すべきポイントは次の2つだ:
- ローカル環境でも使いやすい
- クラウド側に手厚いサポートがある
Docker なんかを利用して、個人開発スケールでも利用しやすいものであることは必要だろう
そして、これをそのままクラウドサービスにまかせても大丈夫な体制が整っていると移行コストがゼロになってだいぶ嬉しい
……という視点で考えたところ、やはり PostgreSQL を採用することになりそうだ
PostgreSQL
"postgresql docker" などのク エリで調べればわかるように、 Docker 環境における posgresql のサポートは手厚い
cf. https://hub.docker.com/_/postgres
また、 GUI から触れるようにツールも存在する(ありがてえ)
cf. https://hub.docker.com/r/dpage/pgadmin4/
次に、クラウドサービスについて:
前提として、今後 BigQuery を必要とする場面が増えるだろうことを考えて、事業者としては GCP を選択せざるを得ないと思っている (AWS もいいが、2つを比較したときに敢えて AWS を選ぶ理由が私にはなかった)
で、その GCP が提供する「データベース」のサービスのうち、ニーズごとにおすすめされているのが以下のページである
https://cloud.google.com/products/databases
第一に候補として挙げられるのが Cloud SQL for PostgreSQL だろう
もっとも手軽だし、信頼もある(と、思い込んでいる)
さらに、もっとスケールさせたいとかパフォーマンスが欲しくなった場合にも PostgreSQL 向け AlloyDB に乗り換えるという選択肢も取れる
もちろん、これら DB から BigQuery にデータをロードするのは容易い(はず?笑)
DB の準備
PostgreSQL を使うことが確定したところで、どうやって手元のデータを読み込ませるのかということを考える
外部からデータを読み込ませる際に "\COPY" という独自のコマンドを使うようだ
cf. https://www.postgresql.jp/document/9.0/html/sql-copy.html
いちいちシェルコマンドでポチポチやっていくのは苦痛なので、 Python ですべてやらせてしまうことになる
で、もっとも良い選択肢と思われるのが psycopg
である
歴史もあるし、C のラッパーなので速度はそこそこ保証されているはずだ
特に、copy_from()
がサポートされているので、膨大なファイル群にも対応しやすいだろう
また、大量にロードする際に速度が著しく落ちる場合の対策も挙げられている (加えて、まだよくわかっていないが「パイプライン機能」なるものをつかうとよりよいらしい?← クエリを絶え間なく送れるからと言う話かも)
cf. https://www.enterprisedb.com/blog/7-best-practice-tips-postgresql-bulk-data-loading
テーブル構造など、適宜考えなければならないっぽいことはあるが、とりあえず「状態」として DB を持つことができそうな筋道は立てられた
まとめ
- GCP 上の Cloud SQL for PostgreSQL (or Alloy DB) を採用する
- ↑ のために、PostgreSQL を採用する
- Docker コンテナで立ててローカルで触ってみる
- ↑ には pgAdmin というツールが使える(もちろんクラウドにおいた場合にも使えるはず)
- データのロードには
\COPY
を用いるが、 Python のライブラリpsycopg
(C のラッパー)を採用するとよさそう - ↑
/data
ディレクトリ以下を探る python スクリプトを書いて、大量にロードできるようにしましょう
こんな感じだろうか
おそらく速度面で色々改善があると思われるが、とりあえず今の段階では考えないことにする
ジャパンカップ、あるいは有馬記念までには予測をもとに勝馬投票券を購入できるようにしたい……!