カテゴリー
コンピューター

k1LoW/tbls 。PostgreSQL ではデータベースの public スキーマでのみ `detectVirtualRelations` が発動する。ユーザ用に作成されたスキーマ (例えば `CREATE SCHEMA AUTHORIZATION joe;`) のテーブルでは `detectVirtualRelations` は発動しなかった

参考

やってみた。まずはデータベース public スキーマで detectVirtualRelations が発動することを確認する。

まず、環境は k1LoW/tbls を初めて使い始めたいのでサンドボックスとして Docker で PostgreSQL 環境を改めて作った – oki2a24 で準備したものを使用した。

実行したコマンドまとめ。

DB テーブルの準備

psql -U postgres

-- ユーザー・DB 作成
CREATE USER "user1" WITH PASSWORD 'password1' CREATEDB;
CREATE DATABASE "db1" WITH OWNER "user1";

-- 接続
\c "db1" "user1"

-- テーブル作成
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL
);
CREATE TABLE roles (
    id SERIAL PRIMARY KEY,
    role_name VARCHAR(255) NOT NULL
);
CREATE TABLE role_user (
    user_id INT NOT NULL,
    role_id INT NOT NULL
);
CREATE TABLE posts (
    id SERIAL PRIMARY KEY,
    user_id INT NOT NULL,
    title VARCHAR(255) NOT NULL,
    content TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 確認
\d

tbls 実行コマンド。 先ほど作成したデータベース、テーブルに対して、スーパーユーザー postgres で tbls を実行する。

cat > .tbls.yml <<EOF
dsn: pg://postgres:password@localhost:5432/db1?sslmode=disable
detectVirtualRelations:
  enabled: true
  strategy: default
EOF

tbls doc --rm-dist

結果。

外部キーは無しのテーブルだが、 detectVirtualRelations によって posts, role_user にリレーションが貼られていることを確認できた!

public スキーマではなく、別のスキーマでも自動リレーション検出により貼られるのか?

-- ユーザー・DB 作成
CREATE USER "user2" WITH PASSWORD 'password2' CREATEDB;
CREATE DATABASE "db2" WITH OWNER "user2";

-- 接続
\c "db2" "user2"

-- スキーマ作成
CREATE SCHEMA AUTHORIZATION "user2";
\dn

-- テーブル作成
-- 省略

-- 確認
\d

別DBになるので .tbls.yml も作り直す。

cat > .tbls.yml <<EOF
dsn: pg://postgres:password@localhost:5432/db2?sslmode=disable
detectVirtualRelations:
  enabled: true
  strategy: default
EOF

tbls doc --rm-dist

前回と同様テーブルに外部キーは無し、かつ、 detectVirtualRelations を設定した。 ところが tbls doc を実行しとたころ、期待とは異なり posts, role_user にリレーションは貼られていなかった。 違いは、 public スキーマではなく、ユーザ名のスキーマに属するテーブルという点のみ。

おわりに

PostgreSQL のデータベースで、 public スキーマではなくそれ以外のスキーマにテーブル等が属しているものを扱う機会があります。

このデータベースは Laravel を通して利用され、テーブル同士のリレーションは Laravel の規約に沿っています。

つまり、 users テーブルがあり、このテーブルにリレーションを作りたい時はそのテーブルに user_id というカラムがあります。

それで、諸般の事情により user_id には外部キーが設定されていません。普通にあることだと思います。

このようなデータベースに対して、 k1LoW/tbls を実行してリレーション付きの状態のデータベースドキュメントを作りたいと思いました。

結果は、、、ダメでした。ドキュメントは生成できたものの、 detectVirtualRelations 自動検知によるリレーションが設定されないのです。 初めて k1LoW/tbls を利用したのがこのデータベースだったため、 detectVirtualRelations は実は機能しない?という可能性をまず除外できる検証を行う必要がありました。 それで、 public スキーマとそうでないスキーマで detectVirtualRelations の発動を確認したのが本投稿となります。

疑問が確認でき、とても解決に近づいた感覚があります♪ 以上です。

コメントを残す