2020-01-14 15:57:45 +03:00
.. meta ::
:description: Insert an object into the database using a mutation
:keywords: hasura, docs, mutation, insert
2020-03-11 22:42:36 +03:00
.. _insert:
2018-09-11 14:11:24 +03:00
Insert mutation
===============
2018-12-03 15:12:24 +03:00
.. contents :: Table of contents
:backlinks: none
:depth: 1
:local:
2019-01-21 12:20:14 +03:00
Auto-generated insert mutation schema
-------------------------------------
2019-02-06 09:39:36 +03:00
**For example** , the auto-generated schema for the insert mutation field for a table `` article `` looks like this:
2018-12-03 15:12:24 +03:00
.. code-block :: graphql
insert_article (
objects: [article_insert_input!]!
on_conflict: article_on_conflict
): article_mutation_response
# response of any mutation on the table "article"
type article_mutation_response {
# number of affected rows by the mutation
affected_rows: Int!
2020-05-18 14:13:57 +03:00
# data of the affected rows by the mutation
2018-12-03 15:12:24 +03:00
returning: [article!]!
}
2020-02-25 18:30:00 +03:00
# single object insert (supported from v1.2.0)
insert_article_one (
object: article_insert_input!
on_conflict: article_on_conflict
): article
2018-12-03 15:12:24 +03:00
As you can see from the schema:
- `` objects `` argument is necessary and you can pass multiple `` objects `` to the mutation.
2020-03-11 22:42:36 +03:00
- You can pass an `` on_conflict `` argument to convert the mutation to an :ref: `upsert mutation <upsert>` .
2018-12-03 15:12:24 +03:00
- You can return the number of affected rows and the affected objects (with nested objects) in the response.
2020-02-25 18:30:00 +03:00
- You can use the single object insert to get the inserted object directly as the mutation response.
2018-12-03 15:12:24 +03:00
2019-09-11 10:17:14 +03:00
See the :ref: `insert mutation API reference <insert_upsert_syntax>` for the full specifications.
2019-02-06 09:39:36 +03:00
2019-01-21 12:20:14 +03:00
.. note ::
2019-03-22 10:08:42 +03:00
If a table is not in the `` public `` Postgres schema, the insert mutation field will be of the format
`` insert_<schema_name>_<table_name> `` .
2019-01-21 12:20:14 +03:00
2018-12-03 15:12:24 +03:00
Insert a single object
----------------------
2019-09-11 10:17:14 +03:00
**Example:** Insert a new `` article `` object and return the inserted article object in the response:
2018-09-11 14:11:24 +03:00
.. graphiql ::
:view_only:
:query:
2020-02-25 18:30:00 +03:00
mutation insert_single_article {
insert_article_one(
object: {
title: "Article 1",
content: "Sample article content",
author_id: 3
2018-09-11 14:11:24 +03:00
}
2020-02-25 18:30:00 +03:00
) {
id
title
2018-09-11 14:11:24 +03:00
}
}
:response:
{
"data": {
2020-02-25 18:30:00 +03:00
"insert_article_one": {
"id": 21,
"title": "Article 1"
2018-09-11 14:11:24 +03:00
}
}
}
2019-04-17 16:37:42 +03:00
Using variables:
2018-09-11 14:11:24 +03:00
.. graphiql ::
:view_only:
:query:
2020-02-25 18:30:00 +03:00
mutation insert_single_article($object: article_insert_input! ) {
insert_article_one(object: $object) {
id
title
2018-09-11 14:11:24 +03:00
}
}
:response:
{
"data": {
2020-02-25 18:30:00 +03:00
"insert_article_one": {
"id": 21,
"title": "Article 1"
2018-09-11 14:11:24 +03:00
}
}
}
2019-01-15 17:34:39 +03:00
:variables:
{
2020-02-25 18:30:00 +03:00
"object": {
"title": "Article 1",
"content": "Sample article content",
"author_id": 3
}
2019-01-15 17:34:39 +03:00
}
2018-09-11 14:11:24 +03:00
2020-02-25 18:30:00 +03:00
.. admonition :: Supported from
The `` insert_<object>_one `` mutation is supported in versions `` v1.2.0 ``
and above.
2018-09-11 14:11:24 +03:00
Insert multiple objects of the same type in the same mutation
-------------------------------------------------------------
2019-09-11 10:17:14 +03:00
**Example:** Insert 2 new `` article `` objects and return both the article objects in the response:
2018-09-11 14:11:24 +03:00
.. graphiql ::
:view_only:
:query:
2020-02-25 18:30:00 +03:00
mutation insert_multiple_articles {
2018-09-11 14:11:24 +03:00
insert_article(
objects: [
{
title: "Article 2",
content: "Sample article content",
author_id: 4
},
{
title: "Article 3",
content: "Sample article content",
author_id: 5
}
]
) {
returning {
id
title
}
}
}
:response:
{
"data": {
"insert_article": {
"affected_rows": 2,
"returning": [
{
"id": 22,
"title": "Article 2"
},
{
"id": 23,
"title": "Article 3"
}
]
}
}
}
2020-02-25 18:30:00 +03:00
Using variables:
.. graphiql ::
:view_only:
:query:
mutation insert_multiple_articles($objects: [article_insert_input!]! ) {
insert_article(objects: $objects) {
returning {
id
title
}
}
}
:response:
{
"data": {
"insert_article": {
"affected_rows": 2,
"returning": [
{
"id": 22,
"title": "Article 2"
},
{
"id": 23,
"title": "Article 3"
}
]
}
}
}
:variables:
{
"objects": [
{
"title": "Article 2",
"content": "Sample article content",
"author_id": 4
},
{
"title": "Article 3",
"content": "Sample article content",
"author_id": 5
}
]
}
2018-12-03 15:12:24 +03:00
Insert an object and get a nested object in response
----------------------------------------------------
2019-09-11 10:17:14 +03:00
**Example:** Insert a new `` article `` object and return the inserted article object with its author in the response:
2018-10-05 18:13:51 +03:00
.. graphiql ::
:view_only:
:query:
mutation insert_article {
insert_article(
objects: [
{
title: "Article 1",
content: "Sample article content",
2018-11-19 13:43:17 +03:00
author_id: 3
2018-10-05 18:13:51 +03:00
}
]
) {
returning {
id
title
author {
id
name
}
}
}
}
:response:
{
"data": {
"insert_article": {
2018-11-19 13:43:17 +03:00
"affected_rows": 1,
2018-10-05 18:13:51 +03:00
"returning": [
{
"id": 21,
"title": "Article 1",
"author": {
"id": 3,
"name": "Sidney"
}
}
]
}
}
}
2019-09-05 15:51:00 +03:00
.. _nested_inserts:
2019-09-04 11:47:55 +03:00
Insert an object along with its related objects through relationships
---------------------------------------------------------------------
2018-10-05 18:13:51 +03:00
2019-11-28 17:50:47 +03:00
One-to-one / One-to-many relationships
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Let's say an `` author `` has an `` object relationship `` called `` address `` to the `` addresses `` table and an
`` array relationship `` called `` articles `` to the `` articles `` table.
**Example:** Insert an `` author `` along with their `` address `` and a few `` articles `` .
2018-09-11 14:11:24 +03:00
.. graphiql ::
:view_only:
:query:
2019-09-04 11:47:55 +03:00
mutation insertData {
insert_authors
(objects: [
2018-09-11 14:11:24 +03:00
{
2019-09-04 11:47:55 +03:00
name: "John",
address: {
2018-11-19 13:43:17 +03:00
data: {
2019-09-04 11:47:55 +03:00
location: "San Francisco"
2018-11-19 13:43:17 +03:00
}
2019-09-04 11:47:55 +03:00
},
articles: {
data: [
{
title: "GraphQL Guide",
content: "Let's see what we can do with GraphQL"
},
{
title: "Authentication Guide",
content: "Let's look at best practices for authentication"
}
]
2018-11-19 13:43:17 +03:00
}
2018-09-11 14:11:24 +03:00
}
]
) {
2018-11-19 13:43:17 +03:00
affected_rows
2018-09-11 14:11:24 +03:00
returning {
id
2019-09-04 11:47:55 +03:00
name
address_id
address {
2018-09-11 14:11:24 +03:00
id
2019-09-04 11:47:55 +03:00
location
}
articles {
id
title
author_id
2018-09-11 14:11:24 +03:00
}
}
}
}
:response:
{
"data": {
2019-09-04 11:47:55 +03:00
"insert_authors": {
"affected_rows": 4,
2018-09-11 14:11:24 +03:00
"returning": [
{
2019-09-04 11:47:55 +03:00
"id": 26,
"name": "John",
"address_id": 27,
"address": {
"id": 27,
"location": "San Francisco"
},
"articles": [
{
"id": 28,
"title": "GraphQL Guide",
"author_id": 26
},
{
"id": 29,
"title": "Authentication Guide",
"author_id": 26,
}
]
2018-09-11 14:11:24 +03:00
}
]
}
}
}
2019-09-04 11:47:55 +03:00
**How it works**
A nested insert mutation is processed as follows:
2019-11-28 17:50:47 +03:00
1. The object relationship objects are inserted first, i.e. in this case, the `` address `` is inserted and its `` id `` is
collected in this step.
2019-09-04 11:47:55 +03:00
2019-11-28 17:50:47 +03:00
2. The parent object is inserted next. i.e. in this case, the `` author `` is now inserted with the `` address_id `` being set
to the `` id `` of the address that was inserted. Because of this, it is not allowed to pass `` address_id `` in the
author object if you are also providing data for the address relationship.
2019-09-04 11:47:55 +03:00
The `` id `` of the author is collected in this step.
2019-11-28 17:50:47 +03:00
3. The array relationship objects are inserted at the end. i.e. in this case, the `` articles `` are now inserted with their
`` author_id `` set to the author's `` id `` collected in the step 2. Hence, it's not possible to specify `` author_id ``
in the data for the articles relationship.
Many-to-many relationships
^^^^^^^^^^^^^^^^^^^^^^^^^^
2019-12-26 15:05:37 +03:00
Let's say the `` articles `` has a :ref: `many-to-many relationship <many_to_many_modelling>` with the `` tags `` table via
2019-11-28 17:50:47 +03:00
a bridge table `` article_tags `` .
**Example:** Insert an `` article `` along with a few `` tags `` .
.. graphiql ::
:view_only:
:query:
mutation insertArticle {
insert_articles(objects: [
{
title: "How to make fajitas",
content: "Guide on making the best fajitas in the world",
author_id: 3,
article_tags: {
data: [
{
tag: {
data: {
label: "Recipes"
},
on_conflict: {
constraint: tags_label_key,
update_columns: [label]
}
}
},
{
tag: {
data: {
label: "Cooking"
},
on_conflict: {
constraint: tags_label_key,
update_columns: [label]
}
}
}
]
}
}
]) {
affected_rows
returning {
id
title
content
author_id
article_tags {
tag {
label
}
}
}
}
}
:response:
{
"data": {
"insert_articles": {
"affected_rows": 5,
"returning": [
{
"author_id": 3,
"article_tags": [
{
"tag": {
"label": "Recipes"
}
},
{
"tag": {
"label": "Cooking"
}
}
],
"content": "Guide on making the best fajitas in the world",
"id": 34,
"title": "How to make fajitas"
}
]
}
}
}
**How it works**
1. The parent object (from the perspective of `` article `` ) is inserted first i.e. the `` article `` is inserted.
The `` id `` of the article is collected in this step.
2. The array relationship objects (from the perspective of `` article `` ) are inserted next i.e. the
`` article_tags `` are inserted.
1. The object relationship objects (from the perspective of `` article_tags `` ) are inserted now i.e.
the `` tags `` are now inserted.
The `` ids `` of the tags are collected in this step.
2. The parent object (from the perspective of `` article_tags `` ) is inserted at the end i.e. the
`` article_tags `` are now inserted with their `` article_id `` set to the article's `` id `` collected in step 1.
The `` tag_id `` is set to the tag's `` id `` collected in step 2.1. Hence, it’ s not possible to specify
`` article_id `` and `` tag_id `` in the data for the `article_tags` relationship.
**on_conflict**
`` on_conflict `` can be passed as an argument in a nested insert statement. In our example, we say that if the unique key (`` label `` ) already
exists for a tag, we update the `` label `` of this respective tag (see :ref: `nested upsert caveats <nested-upsert-caveats>` ).
2019-09-04 11:47:55 +03:00
2019-12-03 17:18:35 +03:00
Insert an object with a JSONB field
-----------------------------------
**Example:** Insert a new `` author `` object with a JSONB `` address `` field:
2019-02-06 09:39:36 +03:00
.. graphiql ::
:view_only:
:query:
mutation insert_author($address: jsonb) {
insert_author (
objects: [
{
name: "Ash",
address: $address
}
]
) {
affected_rows
returning {
id
name
address
}
}
}
:response:
{
"data": {
"insert_author": {
"affected_rows": 1,
"returning": [
{
"id": 1,
"name": "Ash",
"address": {
"city": "Bengaluru",
"phone": "9090909090",
"state": "Karnataka",
"pincode": 560095,
"street_address": "161, 19th Main Road, Koramangala 6th Block"
}
}
]
}
}
}
:variables:
{
"address": {
"street_address": "161, 19th Main Road, Koramangala 6th Block",
"city": "Bengaluru",
"phone": "9090909090",
"state": "Karnataka",
"pincode": 560095
}
}
2019-12-03 17:18:35 +03:00
Insert an object with an ARRAY field
------------------------------------
To insert fields of array types, you currently have to pass them as a `Postgres array literal <https://www.postgresql.org/docs/current/arrays.html#ARRAYS-INPUT> `_ .
**Example:** Insert a new `` author `` with a text array `` emails `` field:
.. graphiql ::
:view_only:
:query:
mutation insert_author {
insert_author (
objects: [
{
name: "Ash",
emails: "{ash@ash.com, ash123@ash.com}"
}
]
) {
affected_rows
returning {
id
name
emails
}
}
}
:response:
{
"data": {
"insert_author": {
"affected_rows": 1,
"returning": [
{
"id": 1,
"name": "Ash",
"emails": ["ash@ash.com", "ash123@ash.com"]
}
]
}
}
}
Using variables:
.. graphiql ::
:view_only:
:query:
mutation insert_author($emails: _text) {
insert_author (
objects: [
{
name: "Ash",
emails: $emails
}
]
) {
affected_rows
returning {
id
name
emails
}
}
}
:response:
{
"data": {
"insert_author": {
"affected_rows": 1,
"returning": [
{
"id": 1,
"name": "Ash",
"emails": ["ash@ash.com", "ash123@ash.com"]
}
]
}
}
}
:variables:
{
"emails": "{ash@ash.com, ash123@ash.com}"
}
2018-12-03 15:12:24 +03:00
Set a field to its default value during insert
----------------------------------------------
2018-09-11 14:11:24 +03:00
2018-11-06 11:37:17 +03:00
To set a field to its `` default `` value, just omit it from the input object, irrespective of the
2020-03-11 22:42:36 +03:00
:ref: `default value configuration <postgres_defaults>` i.e. via Postgres defaults or using column presets.
2018-09-11 14:11:24 +03:00
2019-09-11 10:17:14 +03:00
**Example:** If the default value of `` id `` is set to auto-incrementing integer, there's no need to pass the `` id `` field to the input object:
2018-09-11 14:11:24 +03:00
.. graphiql ::
:view_only:
:query:
mutation insert_article_with_def_id {
insert_article(
objects: [
{
title: "Article 1",
content: "Sample article content",
author_id: 3
}
]
) {
returning {
id
title
}
}
}
:response:
{
"data": {
"insert_article": {
"affected_rows": 1,
"returning": [
{
"id": 21,
"title": "Article 1"
}
]
}
}
}
2019-02-06 09:39:36 +03:00
Set a field to NULL during insert
2018-12-03 15:12:24 +03:00
---------------------------------
2018-09-11 14:11:24 +03:00
If a field is `` nullable `` in the database, to set its value to `` null `` , either pass its value as `` null `` or
just omit it from the input object.
2019-09-11 10:17:14 +03:00
**Example:** If `` age `` is a nullable field, to set it to `` null `` , either don't pass the age field to the input object
or pass it as `` null `` :
2018-09-11 14:11:24 +03:00
.. graphiql ::
:view_only:
:query:
mutation insert_author_with_null_age {
insert_author(
objects: [
{
name: "Jeff",
}
]
) {
returning {
id
name
age
}
}
}
:response:
{
"data": {
"insert_author": {
"returning": [
{
"id": 11,
"name": "Jeff",
"age": null
}
]
}
}
}
OR
.. graphiql ::
:view_only:
:query:
mutation insert_author_with_null_age {
insert_author(
objects: [
{
name: "Jeff",
age: null
}
]
) {
returning {
id
name
age
}
}
}
:response:
{
"data": {
"insert_author": {
"returning": [
{
"id": 11,
"name": "Jeff",
"age": null
}
]
}
}
2018-10-05 18:13:51 +03:00
}