Modelling one-to-one table relationships / Hasura ドキュメント翻訳
TweetIntroduction
テーブル間の「一対一 = one to one」の関係性は、unique foreign key 制限 = unique foreign key constraint を用いて実装することができます。
A one-to-one relationship between two tables can be established via a unique foreign key constraint.
以下のスキーマを持つ二つのテーブルあるとしましょう。
Say we have the following two tables in our database schema:
author (
id SERIAL PRIMARY KEY,
name TEXT
)
passport_info (
id SERIAL PRIMARY KEY,
owner_id INT NOT NULL
passport_number TEXT
...
)この二つのテーブルは one-to-one relationship によって関連づけられています。つまり次のような特徴を持ちます。
authorは一つのpassport_infoを持つ(訳注:正確には 0 もしくは 1)passport_infoは一つのownerを持つ(訳注:こちらは 0 には絶対にならない)
These two tables are related via a one-to-one relationship. i.e.:
an author can have one passportinfo a passportinfo has one owner
Step 1: Set up a table relationship in the database
one-to-one relationship を作るためには dabase に対して以下の操作を加えます。
This one-to-one relationship can be established in the database by:
-
foreign key constraint機能を用いて、passport_infoテーブルとauthorテーブルを紐付けます。passport_info.owner_idからauthor.idに対して制限を設けます。 -
passport_infoのowner_idに対してunique constraintを設けます。 -
Adding a foreign key constraint from the passportinfo table to the author table using the ownerid and id columns of the tables respectively
-
Adding a unique constraint to the ownerid column for the passportinfo table
これらの操作によって、passport_info テーブルの owner_id を持つ author が必ず存在することが保証されます。(訳注:FK によって)また passport_info テーブルの owner_id が特定の値を持つカラムは、必ず一つであることが保証されます。(訳注:unique constraint によって)
This will ensure that the value of the ownerid column in passportinfo table is present in the id column of the author table and there will be only one row with a particular owner_id.
Step 2: Set up GraphQL relationships
GraphQL API を使って nested objects query にアクセスできるようにするためには、以下の操作をとおして relationships を定義します。
To access the nested objects via the GraphQL API, create the following relationships:
-
一つめの Object relationship を作成します。
author テーブルからpassport_infoにアクセスできるようにするために、author テーブルのRelationships設定画面から次のように設定します。id -> passport_info :: owner_id -
二つめの Object relationship を作成します。
passport_info テーブルからownerにアクセスできるようにするために、passport_info テーブルのRelationships設定画面から次のように設定します。owner_id -> author :: id -
Object relationship, passportinfo from the author table using id -> passportinfo :: owner_id
-
Object relationship, owner from the passportinfo table using ownerid -> author :: id
Step 3: Query using relationships
設定が完了しましたので、passport_info をともなった author リストのフェッチをおこなってみましょう。
We can now:
fetch a list of authors with their passport_info:

owner 情報をともなった passport_info リストのフェッチをおこなってみましょう。
fetch a list of passport_infos with their owner:

Current limitations with nested mutations
one-to-one relationships において現状、nested mutations は一方向にしか正常に動作しません。
With one-to-one relationships, currently nested mutations will work only in one of the two directions.
今回の例でいうと、passport_info に対する mutation を発行し、nest された owner を伴って passport_info を追加することは可能なのですが、反対に author に対する mutation を発行し、nest された passport_info を伴って author を追加しようとすると constraint violation error が発生してしまいます。
In our example, inserting a passportinfo with their nested owner will work seamlessly but trying to insert an author with their nested passportinfo will throw a constraint violation error.
これは Hasura GraphQL が nested mutation を扱う方法が原因です。(これについては この記事 が詳細を説明しています。)nested object は親よりも先に inert されます。つまり上記のエラーが起きる例では passport_info の方が先に insert されるので、その時点では owner が存在しないため owner_id が null になってしまいます。結果として passport_info.owner_id に Not-NULL 制限をかけているのであればこの時点でエラーが発生します。(訳注:passport_info に対する mutation を発行する方法もどうやるのかよくわからない。わかる人がいれば訳者まで是非連絡を)
This is due to the way Hasura GraphQL engine currently handles nested mutations (described in detail here). As nested object relations are inserted before the parent, the passportinfo will be attempted to be inserted first and the value of its ownerid will be attempted to be set as the id of the author. Due to this, based on whether the ownerid of passportinfo is nullable or not, a Not-NULL violation error will be thrown either for the ownerid field of passportinfo or the id field of author.