Modelling one-to-many table relationships¶
Table of contents
Introduction¶
A one-to-many
relationship between two tables can be established via a foreign key constraint.
Say we have the following two tables in our database schema:
authors (
id SERIAL PRIMARY KEY,
name TEXT
)
articles (
id SERIAL PRIMARY KEY,
author_id INT
title TEXT
...
)
These two tables are related via a one-to-many
relationship. i.e:
- an
author
can have manyarticles
- an
article
has oneauthor
Step 1: Set up a table relationship in the database¶
This one-to-many
relationship can be established in the database by:
- Adding a foreign key constraint from the
articles
table to theauthors
table using theauthor_id
andid
columns of the tables respectively.
This will ensure that the value of author_id
column in the articles
table is present in the id
column of
the authors
table.
Step 2: Set up GraphQL relationships¶
To access the nested objects via the GraphQL API, create the following relationships:
- Array relationship,
articles
fromauthors
table usingarticles :: author_id -> id
- Object relationship,
author
fromarticles
table usingauthor_id -> authors :: id
Query using one-to-many relationships¶
We can now:
fetch a list of
authors
with theirarticles
:GraphiQL1query {
2authors {
3id
4name
5articles {
6id
7title
8}
9}
10}
Variablesx1
xxxxxxxxxx
{
"data": {
"authors": [
{
"id": 1,
"name": "Justin",
"articles": [
{
"id": 15,
"title": "vel dapibus at"
},
{
"id": 16,
"title": "sem duis aliquam"
}
]
},
{
"id": 2,
"name": "Beltran",
"articles": [
{
"id": 2,
"title": "a nibh"
},
{
"id": 9,
"title": "sit amet"
}
]
}
]
}
}
fetch a list of
articles
with theirauthor
:GraphiQL101query {
2articles {
3id
4title
5author {
6id
7name
8}
9}
10}
Variables11
xxxxxxxxxx
{
"data": {
"articles": [
{
"id": 1,
"title": "sit amet",
"author": {
"id": 4,
"name": "Anjela"
}
},
{
"id": 2,
"title": "a nibh",
"author": {
"id": 2,
"name": "Beltran"
}
}
]
}
}
Insert using one-to-many relationships¶
We can now:
- insert an
author
with theirarticles
where the author might already exist (assume uniquename
forauthor
):
GraphiQL
30
1
mutation UpsertAuthorWithArticles {
2
insert_author(objects: {
3
name: "Felix",
4
articles: {
5
data: [
6
{
7
title: "Article 1",
8
content: "Article 1 content"
9
},
10
{
11
title: "Article 2",
12
content: "Article 2 content"
13
}
14
]
15
}
16
},
17
on_conflict: {
18
constraint: author_name_key,
19
update_columns: [name]
20
}
21
) {
22
returning {
23
name
24
articles {
25
title
26
content
27
}
28
}
29
}
30
}
Variables
1
1
xxxxxxxxxx
{
"data": {
"insert_author": {
"returning": [
{
"name": "Felix",
"articles": [
{
"title": "Article 1",
"content": "Article 1 content"
},
{
"title": "Article 2",
"content": "Article 2 content"
}
]
}
]
}
}
}
- insert
articles
with theirauthor
where theauthor
might already exist (assume uniquename
forauthor
):
GraphiQL
38
1
mutation upsertArticleWithAuthors {
2
insert_article(objects: [
3
{
4
title: "Article 1",
5
content: "Article 1 content",
6
author: {
7
data: {
8
name: "Alice"
9
},
10
on_conflict: {
11
constraint: author_name_key,
12
update_columns: [name]
13
}
14
}
15
},
16
{
17
title: "Article 2",
18
content: "Article 2 content",
19
author: {
20
data: {
21
name: "Alice"
22
},
23
on_conflict: {
24
constraint: author_name_key,
25
update_columns: [name]
26
}
27
}
28
}
29
]) {
30
returning {
31
title
32
content
33
author {
34
name
35
}
36
}
37
}
38
}
Variables
1
1
xxxxxxxxxx
{
"data": {
"insert_article": {
"returning": [
{
"title": "Article 1",
"content": "Article 1 content",
"author": {
"name": "Alice"
}
},
{
"title": "Article 2",
"content": "Article 2 content",
"author": {
"name": "Alice"
}
}
]
}
}
}
Note
You can avoid the on_conflict
clause if you will never have conflicts.