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.