Creating relationships¶
Table of contents
Introduction¶
A relationship from one table/view to another can be created by defining a link between a column of the table/view to a column of the other table/view.
Typically, relationships are defined using foreign-key constraints. But in some cases, it might not be possible to use foreign-key constraints to create the relation. For example, while trying to create a relationship involving a view as foreign-keys can’t be created on views.
Using foreign keys¶
Say we created two tables, author(id, name)
and article(id, title, content, rating, author_id)
.
Let us now connect these tables to enable nested queries using a foreign-key:
Step 1: Add foreign-key constraint¶
Let’s add a foreign-key constraint to the author_id
column in the article
table.
In the console, navigate to the Modify
tab of the article
table. Click the Add
button in
the Foreign Keys section and configure the author_id
column as a foreign-key for the id
column in
the author
table:
Create a migration manually and add the following SQL statement to the up.sql
file:
ALTER TABLE article
ADD FOREIGN KEY (author_id) REFERENCES author(id);
Add the following statement to the down.sql
file in case you need to roll back the above statement:
ALTER TABLE article
DROP CONSTRAINT article_author_id_fkey;
Apply the migration by running:
hasura migrate apply
You can add a foreign-key constraint using the run_sql metadata API:
POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "run_sql",
"args": {
"sql": "ALTER TABLE article ADD FOREIGN KEY (author_id) REFERENCES author(id);"
}
}
Step 2: Create an object relationship¶
Each article has one author. This is an object relationship
.
The console infers potential relationships using the foreign-key created above and recommends these in the
Relationships
tab of the article
table.
Add an object relationship
named author
for the article
table as shown here:
You can add an object relationship in the tables.yaml
file inside the metadata
directory:
- table:
schema: public
name: article
object_relationships:
- name: author
using:
foreign_key_constraint_on: author_id
- table:
schema: public
name: author
Apply the metadata by running:
hasura metadata apply
You can create an object relationship by using the create_object_relationship metadata API:
POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "create_object_relationship",
"args": {
"table": "article",
"name": "author",
"using": {
"foreign_key_constraint_on": "author_id"
}
}
}
We can now run a nested object query that is based on this object relationship
.
Fetch a list of articles and each article’s author:
query {
article {
id
title
author {
id
name
}
}
}
Step 3: Create an array relationship¶
An author can write multiple articles. This is an array relationship
.
You can add an array relationship
in the same fashion as an object relationship
as shown above.
On the console, add an array relationship
named articles
for the author
table as shown here:
We can now run a nested object query that is based on this array relationship
.
You can add an array relationship in the tables.yaml
file inside the metadata
directory:
- table:
schema: public
name: article
object_relationships:
- name: author
using:
foreign_key_constraint_on: author_id
- table:
schema: public
name: author
array_relationships:
- name: articles
using:
foreign_key_constraint_on:
column: author_id
table:
schema: public
name: article
Apply the metadata by running:
hasura metadata apply
You can create an array relationship by using the create_array_relationship metadata API:
POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "create_array_relationship",
"args": {
"table": "author",
"name": "articles",
"using": {
"foreign_key_constraint_on" : {
"table" : "article",
"column" : "author_id"
}
}
}
}
Fetch a list of authors and a nested list of each author’s articles:
query {
author {
id
name
articles {
id
title
}
}
}
Using manual relationships¶
Let’s say you have a table author (id, name)
and a view author_avg_rating (id, avg)
which has the
average rating of articles for each author.
Let us now create an object relationship
called avg_rating
from the author
table to the
author_avg_rating
view using a manual relationship:
Step 1: Open the manual relationship section
- Open the console and navigate to the
Data -> author -> Relationships
tab. - Click on the
Configure
button:
Step 2: Define the relationship
The above step will open up a section as shown below:
In this case:
- Relationship Type will be:
Object Relationship
- Relationship Name can be:
avg_rating
- Reference will be:
id -> author_avg_rating . id
(similar to defining a foreign-key)
Step 3: Create the relationship
Now click on the Save
button to create the relationship.
You can add a manual relationship in the tables.yaml
file inside the metadata
directory:
- table:
schema: public
name: article
- table:
schema: public
name: author
object_relationships:
- name: avg_rating
using:
manual_configuration:
remote_table:
schema: public
name: author_average_rating
column_mapping:
id: author_id
- table:
schema: public
name: author_average_rating
Apply the metadata by running:
hasura metadata apply
You can add a manual relationship by using the create_object_relationship metadata API:
POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "create_object_relationship",
"args": {
"table": "author",
"name": "avg_rating",
"using": {
"manual_configuration": {
"remote_table": "author_average_rating",
"column_mapping": {
"id": "author_id"
}
}
}
}
}
We can now run a nested object query that is based on this object relationship
.
Fetch a list of authors with the average rating of their articles:
query {
author {
id
name
avg_rating {
avg
}
}
}
Tracking existing relationships inferred via foreign-keys¶
As mentioned in the Introduction section above, relationships can be inferred via foreign-keys that exist in your database:
The console infers potential relationships using existing foreign-keys and recommends these on the Data -> Schema
page
You can choose to track the relationships individually using the Track
buttons or hit the Track all
button to
track all the inferred relationships in one go.
You can add relationships in the tables.yaml
file inside the metadata
directory:
- table:
schema: public
name: article
object_relationships:
- name: author
using:
foreign_key_constraint_on: author_id
- table:
schema: public
name: author
array_relationships:
- name: articles
using:
foreign_key_constraint_on:
column: author_id
table:
schema: public
name: article
Apply the metadata by running:
hasura metadata apply
You can create multiple relationships by using the create_object_relationship metadata API and the create_array_relationship metadata API:
POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "bulk",
"args": [
{
"type": "create_object_relationship",
"args": {
"table": "article",
"name": "author",
"using": {
"foreign_key_constraint_on": "author_id"
}
}
},
{
"type": "create_array_relationship",
"args": {
"table": "author",
"name": "articles",
"using": {
"foreign_key_constraint_on" : {
"table" : "article",
"column" : "author_id"
}
}
}
}
]
}