PONOS Advent Calendar 2022 の20日目の記事です。
昨日は@tequila0725さんのBitbucketでPR作成時に表示されるコミットメッセージリストをPR説明テンプレート有りでも表示するでした。
はじめに
Cloud Spannerは計画的ダウンタイムがなく、無制限のスケーリングなど、他のデータベースにはない特徴を持ったデータベースです。
標準のActiveRecordはSpannerには対応していませんが、Googleからactiverecord-spanner-adapterが提供されていますので、そのGemを使って「Ruby on Rails」 + 「Cloud Spanner」の開発することできます。
この記事では、Cloud Spannerエミュレータを使用し、Ruby on Railsでアプリを作り、activerecord-spanner-adapterを使ってテーブルを作成するまでを紹介させていただきます。
Cloud SpannerエミュレータをDockerで起動する
(1)新しいディレクトリを作成する
mkdir ~/rails_spanner_test
cd ~/rails_spanner_test
(2)docker-compose.ymlを作成する
version: '3'
services:
spanner:
container_name: spanner
image: gcr.io/cloud-spanner-emulator/emulator:1.4.3
ports:
- 9010:9010
- 9020:9020
networks:
- test-network
spanner-init:
container_name: spanner-init
image: gcr.io/google.com/cloudsdktool/cloud-sdk:400.0.0-slim
command: >
bash -c 'gcloud config configurations create emulator &&
gcloud config set auth/disable_credentials true &&
gcloud config set project $${PROJECT_ID} &&
gcloud config set api_endpoint_overrides/spanner $${SPANNER_EMULATOR_URL} &&
gcloud spanner instances create $${INSTANCE_NAME} --config=emulator-config --description=Emulator --nodes=1 &&
echo this container keep running && tail -f /dev/null'
environment:
PROJECT_ID: test-project
SPANNER_EMULATOR_URL: http://spanner:9020/
INSTANCE_NAME: test-instance
networks:
- test-network
spanner-cli:
container_name: spanner-cli
image: sjdaws/spanner-cli:latest
environment:
SPANNER_EMULATOR_HOST: spanner:9010
command: ['sh', '-c', 'echo this container keep running && tail -f /dev/null']
networks:
- test-network
networks:
test-network:
driver: bridge
(3)コンテナを起動する
docker-compose up -d
Railsアプリを作成する
以下の環境で実施しました。
- OS: macOS Monterey version 12.6
- Rails: 3.1.1
- rbenv: 1.2.0
- Rails: 7.0.2
(1)Railsのバージョンを3.1.1に設定する
cd ~/rails_spanner_test
rbenv local 3.1.1
(2)新しいRailsアプリを作成する
rails new .
(3)Gemfileにactiverecord-spanner-adapterのGemを追加する
gem 'activerecord-spanner-adapter'
(4)Gemをインストールする
bundle install
※M1 Macを使う場合以下のようなエラーがでると思います。
In Gemfile:
activerecord-spanner-adapter was resolved to 1.2.2, which depends on
google-cloud-spanner was resolved to 2.16.1, which depends on
google-cloud-spanner-admin-database-v1 was resolved to 0.11.0, which depends on
gapic-common was resolved to 0.16.0, which depends on
googleapis-common-protos was resolved to 1.4.0, which depends on
grpc
その場合、少し古いGemとなりますが、Rubygem.orgのアーカイブから、universal-darwinのバージョンを使ってください。
gem "grpc", "~> 1.45.0"
(5)config/database.ymlを修正する
default: &default
adapter: spanner
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 10 } %>
project: test-project
instance: test-instance
development:
<<: *default
database: devdb
test:
<<: *default
database: testdb
production:
<<: *default
database: proddb
(6)動作確認用にモデルを作成する
bin/rails g model user name:string
(7)SPANNER_EMULATOR_HOST環境変数を設定する
アプリケーションが起動すると、クライアント ライブラリは自動的に SPANNER_EMULATOR_HOST をチェックし、エミュレータが実行されている場合は接続します。
export SPANNER_EMULATOR_HOST=localhost:9010
(8)データベースを作成する
bin/rails db:create
(9)マイグレートしてテーブルを作成する
bin/rails db:migrate
Spanner CLIで確認する
usersテーブルが作成されていることが確認できました!
% docker-compose exec spanner-cli spanner-cli -p test-project -i test-instance -d devdb
Connected.
spanner> show tables;
+----------------------+
| Tables_in_devdb |
+----------------------+
| schema_migrations |
| ar_internal_metadata |
| users |
+----------------------+
3 rows in set (0.06 sec)
まとめ
エミュレータと実際のCloud Spannerと異なる部分もありますが、大きな問題はなくローカル環境で開発することができます。
今回、Rails開発者がSpannerを使い始めるきっかけになればと簡単ではありますが記事にさせていただきました。
実際に開発を進める際には、例えば
- ReadOnlyトランザクションを使う場合とRead/Writeトランザクションを使う場合の方法
- バルクインサート
- ミューテーション
- インターリーブ
などの必要な情報がありますので、まず以下のExamplesやLimitationsを読むことをお勧めします。
明日は@MilayYadokariさんです!