database.build (formerly postgres.new)にrails db:migrateしてER図を眺めたりしてみる
軽いネタです。
database.build (formerly postgres.new) とは
database.build
(旧称:postgres.new
) は、PostgreSQL データベースを簡単に構築・管理するためのプラットフォームです。
GitHubアカウントでログインすると、ブラウザ上でPostgreSQLが立ち上がり(!)、playground的にいろいろ遊べます。
立ち上がるPostgreSQLは、WASMに移植した PGlite
を活用して実装しているとのこと。データは、ブラウザ内のIndexedDB
に保存されるとのことです [1]。
よくある使い方: 対話的にDB設計ができる
たとえばチャット欄に「メルカリみたいなやつ」といれると、そんな感じのものをLLMが作ってくれます。
対話の様子はこんな感じ。animation gif:
画面上の主な機能としては
- E-R図が確認できる
- migrationのためのCREATE TABLE文が確認できる
ということがあります。
また、ダウンロードボタンを押せば、IndexedDBの中身が全部.gzファイルで降ってきます。中身はPostgresの実体ファイルたち。
LiveShare機能でpsql接続できる
LiveShareボタンがあるのでおもむろにこれを押すと
こんな感じで、psqlとかで接続可能なURLを払い出してくれます。
接続先ホストとなっている *.browser.db.build
を利用するにはインターネットが必要です。 (現状 fly.io
が使われている雰囲気。)
これでpsqlで、お手元のブラウザ上で立ち上がっているPostgreSQL(PGLite)に接続できます。
しくみについてはよく理解していませんが、supabaseのブログに書いてあります [2]。
websocketとsql接続用のTCPを仲立ちするproxyがインターネット上にある様子。以下はそのブログからの引用。
今回やってみたこと: railsのタスクでアクセス
空のデータベースを作成・接続先URLをゲット
最初に対話が必要で、「空のデータベース」とか入力するとデータベースを作ってくれます。
LiveShareボタンを押して接続先URLをコピっておきます。
このときブラウザのタブは開いたままで。
rails db:migrateしてみる
手元に適当なrailsアプリがあれば試せます。
自分が動作確認したRailsアプリをログがてら置いておきます:
自分の環境では以下のような前提が必要でした。
- postgresベースであること
- pg gemをビルドしたときに使ったライブラリが比較的新しいものであること
- (postgres16とかだったら問題ないはず。postgres11ベースだとSNIを使うためか動かなかった)
今回 の db/schema.rb はこんな感じ。Eコマースっぽいものにしてみました。 [3]
ActiveRecord::Schema[8.0].define(version: 7) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_catalog.plpgsql"
create_table "cart_items", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "cart_id", null: false
t.uuid "product_id", null: false
t.string "product_name", null: false
t.decimal "product_unit_price", default: "0.0", null: false
t.integer "quantity", default: 0, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["cart_id"], name: "index_cart_items_on_cart_id"
t.index ["product_id"], name: "index_cart_items_on_product_id"
end
create_table "carts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "user_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_carts_on_user_id"
end
create_table "products", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name", null: false
t.text "description", null: false
t.decimal "unit_price", default: "0.0", null: false
t.integer "stock", default: 0, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "purchases", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "cart_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["cart_id"], name: "index_purchases_on_cart_id"
end
create_table "sessions", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "user_id", null: false
t.string "ip_address"
t.string "user_agent"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_sessions_on_user_id"
end
create_table "users", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "email_address", null: false
t.string "password_digest", null: false
t.string "onboarding_status", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email_address"], name: "index_users_on_email_address", unique: true
end
add_foreign_key "sessions", "users"
end
rails db:migrateは以下のようなコマンドで実行しました。
なんとなく RAILS_ENV=test していますが、これはなくてもいいかも。
RAILS_ENV=test DATABASE_URL="<URLをここで利用>" bin/rails db:migrate
ちなみに接続先は米国っぽかったのでだいぶ遅いです。
超時間かかりますがrspecでdbを使うような簡単なテストも動きました。
E-R図に反映された様子を確認
E-R図にちゃんと反映されます。
今回外部キーは1つしか設定してないので、Entity同士のつながりの線は少なくなっています。
チャットでテーブルを説明させる
「今存在するテーブルを説明してください」とか入力すると、返事で教えてくれます
結び
今回は、database.build を使って、手軽にPostgreSQLデータベースを作成し、Railsの db:migrate
を実行してE-R図を眺めてみる、という軽めの実験をしてみました。
米国のサーバーに接続するせいか遅延はあるものの、ブラウザだけで完結する手軽さが魅力ですね。
プロキシもフロントエンドアプリもOSSなので [4]、機会があればセルフホストしてみようかと思いました
-
記憶が定かじゃないけど
enable_extension "pgcrypto"
はあると不都合だった気がするので削除して調整した。それでも動かなかったらすいません。 ↩︎
Discussion