docs/docs/schema/postgres/table-relationships/create.mdx
import GraphiQLIDE from '@site/src/components/GraphiQLIDE'; import Thumbnail from '@site/src/components/Thumbnail'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
A relationship from one table/view/Native Query to another can be created by defining a link between a column of the table/view/Native Query to a column of the other table/view/Native Query.
Typically, relationships between tables are defined using foreign-key constraints. But in some cases, it might not be possible to use foreign-key constraints to create the relationship. For example, while trying to create a relationship involving a view or Native Query since foreign-keys cannot be created on them.
Say we created two tables, authors(id, name) and articles(id, title, content, rating, author_id).
Let us now connect these tables to enable nested queries using a foreign-key:
Let's add a foreign-key constraint to the author_id column in the articles table.
In the Console, navigate to the Modify tab of the articles 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 authors table:
Create a migration manually and add the
following SQL statement to the up.sql file:
ALTER TABLE articles
ADD FOREIGN KEY (author_id) REFERENCES authors(id);
Add the following statement to the down.sql file in case you need to
roll back the above statement:
ALTER TABLE articles
DROP CONSTRAINT articles_author_id_fkey;
Apply the migration by running:
hasura migrate apply
You can add a foreign-key constraint using the run_sql schema API:
POST /v2/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "run_sql",
"args": {
"source": "<db_name>",
"sql": "ALTER TABLE articles ADD FOREIGN KEY (author_id) REFERENCES authors(id);"
}
}
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 articles table.
Add an object relationship named author for the articles table as shown here:
You can add an object relationship in the tables.yaml file inside the metadata directory:
- table:
schema: public
name: articles
object_relationships:
- name: author
using:
foreign_key_constraint_on: author_id
- table:
schema: public
name: authors
Apply the Metadata by running:
hasura metadata apply
You can create an object relationship by using the pg_create_object_relationship Metadata API:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "pg_create_object_relationship",
"args": {
"source": "<db_name>",
"table": "articles",
"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:
<GraphiQLIDE
query={query { articles { id title author { id name } } }}
response={{ "data": { "articles": [ { "id": 1, "title": "sit amet", "author": { "name": "Anjela", "id": 4 } }, { "id": 2, "title": "a nibh", "author": { "name": "Beltran", "id": 2 } }, { "id": 3, "title": "amet justo morbi", "author": { "name": "Anjela", "id": 4 } } ] } }}
/>
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 authors 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: articles
object_relationships:
- name: author
using:
foreign_key_constraint_on: author_id
- table:
schema: public
name: authors
array_relationships:
- name: articles
using:
foreign_key_constraint_on:
column: author_id
table:
schema: public
name: articles
Apply the Metadata by running:
hasura metadata apply
You can create an array relationship by using the pg_create_array_relationship Metadata API:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "pg_create_array_relationship",
"args": {
"source": "<db_name>",
"table": "authors",
"name": "articles",
"using": {
"foreign_key_constraint_on" : {
"table" : "articles",
"column" : "author_id"
}
}
}
}
Fetch a list of authors and a nested list of each author's articles:
<GraphiQLIDE
query={query { authors { id name articles { id title } } }}
response={{ "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" } ] }, { "id": 3, "name": "Sidney", "articles": [ { "id": 6, "title": "sapien ut" }, { "id": 11, "title": "turpis eget" }, { "id": 14, "title": "congue etiam justo" } ] } ] } }}
/>
Let's say you have a table authors (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 authors table to the author_avg_rating view
using a manual relationship:
Step 1: Open the manual relationship section
Data -> authors -> Relationships tab.Add Relationship button:**Step 2: Fill in the relationships details **
Once the widget is open, fill in the name of the relationship and pick a reference source
<Thumbnail src="/img/schema/add-manual-rel-add-name-pick-source.png" alt="Define the relationship name and target" width="700px" />This will open up a "details" section below where you can fill in the rest of the relationship definition
<Thumbnail src="/img/schema/add-manual-rel-fill-details.png" alt="Fill the relationship details" width="700px" />Step 3: Create the relationship
Now click on the Create Relationship button to proceed.
You can add a manual relationship in the tables.yaml file inside the metadata directory:
- table:
schema: public
name: articles
- table:
schema: public
name: authors
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 pg_create_object_relationship Metadata API:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "pg_create_object_relationship",
"args": {
"source": "<db_name>",
"table": "authors",
"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:
<GraphiQLIDE
query={query { authors { id name avg_rating { avg } } }}
response={{ "data": { "authors": [ { "id": 1, "name": "Justin", "avg_rating": { "avg": 2.5 } }, { "id": 2, "name": "Beltran", "avg_rating": { "avg": 3 } }, { "id": 3, "name": "Sidney", "avg_rating": { "avg": 2.6666666666666665 } } ] } }}
/>
As mentioned in the Introduction section above, relationships can be inferred via foreign-keys that exist in your database:
<Tabs groupId="user-preference" className="api-tabs"> <TabItem value="console" label="Console">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: articles
object_relationships:
- name: author
using:
foreign_key_constraint_on: author_id
- table:
schema: public
name: authors
array_relationships:
- name: articles
using:
foreign_key_constraint_on:
column: author_id
table:
schema: public
name: articles
Apply the Metadata by running:
hasura metadata apply
You can create multiple relationships by using the pg_create_object_relationship and the pg_create_array_relationship Metadata APIs:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "bulk",
"args": [
{
"type": "pg_create_object_relationship",
"args": {
"source": "<db_name>",
"table": "articles",
"name": "author",
"using": {
"foreign_key_constraint_on": "author_id"
}
}
},
{
"type": "pg_create_array_relationship",
"args": {
"source": "<db_name>",
"table": "authors",
"name": "articles",
"using": {
"foreign_key_constraint_on" : {
"table" : "articles",
"column" : "author_id"
}
}
}
}
]
}
As mentioned in the Introduction section above, a relationship from a table to a Native Query can only be set up manually.
<Tabs groupId="user-preference" className="api-tabs"> <TabItem value="api" label="API">Given a table named articles and an existing Native Query named get_author,
we can set up a relationship between the two.
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type": "bulk",
"args": [
{
"type": "pg_create_object_relationship",
"args": {
"source": "<db_name>",
"table": "articles",
"name": "author",
"using": {
"manual_configuration": {
"remote_native_query": "get_author",
"column_mapping": {
"id": "author_id"
}
}
}
}
}
]
}