Skip to main content

Mutations

Hugr automatically generates mutation operations for tables (not views). These mutations handle data modifications with support for relationships, transactions, and returning affected data.

Insert Mutations​

Insert single or multiple records:

mutation {
insert_customers(data: {
name: "John Doe"
email: "john@example.com"
status: "active"
}) {
id
name
email
created_at
}
}

Insert with Relations​

Insert related records in a single transaction:

mutation {
insert_customers(data: {
name: "Jane Smith"
email: "jane@example.com"
addresses: [
{
street: "123 Main St"
city: "New York"
type: "billing"
}
{
street: "456 Oak Ave"
city: "Boston"
type: "shipping"
}
]
orders: [
{
order_date: "2024-01-15"
status: "pending"
order_details: [
{
product_id: 1
quantity: 2
unit_price: 50.00
}
]
}
]
}) {
id
name
addresses {
id
type
city
}
orders {
id
status
order_details {
product_id
quantity
}
}
}
}

Return Values​

For tables with primary keys, the mutation returns the inserted record(s). Without primary keys, it returns an OperationResult:

type OperationResult {
affected_rows: Int!
success: Boolean!
message: String
last_id: BigInt
}

Update Mutations​

Update records matching filter conditions:

mutation {
update_customers(
filter: { id: { eq: 123 } }
data: {
email: "newemail@example.com"
updated_at: "2024-01-15T10:00:00Z"
}
) {
affected_rows
success
message
}
}

Bulk Updates​

Update multiple records:

mutation {
update_products(
filter: {
category_id: { eq: 5 }
status: { eq: "active" }
}
data: {
discount_percentage: 15
sale_ends_at: "2024-02-01T00:00:00Z"
}
) {
affected_rows
success
}
}

Conditional Updates​

Use complex filters for targeted updates:

mutation {
update_orders(
filter: {
_and: [
{ status: { eq: "pending" } }
{ created_at: { lt: "2024-01-01" } }
{ customer: { status: { eq: "active" } } }
]
}
data: {
status: "cancelled"
cancelled_reason: "Order expired"
}
) {
affected_rows
}
}

Delete Mutations​

Delete records matching filter conditions:

mutation {
delete_customers(
filter: { id: { eq: 123 } }
) {
affected_rows
success
message
}
}

Bulk Deletes​

Delete multiple records:

mutation {
delete_old_logs(
filter: {
created_at: { lt: "2023-01-01" }
}
) {
affected_rows
}
}

Soft Delete​

For tables with soft delete enabled:

mutation {
delete_customers(
filter: { id: { eq: 123 } }
) {
affected_rows # Record marked as deleted, not physically removed
}
}

To query including soft-deleted records:

query {
customers @with_deleted {
id
name
deleted_at
}
}

Input Types​

Insert Input Type​

Generated for each table, includes all fields and relations:

input customers_mut_input_data {
# Direct fields
name: String!
email: String!
status: String

# Related records (one-to-one/many-to-one)
profile: customer_profiles_mut_input_data

# Related records (one-to-many)
addresses: [customer_addresses_mut_input_data]
orders: [orders_mut_input_data]
}

Update Input Type​

Contains only direct fields (no relations):

input customers_mut_data {
name: String
email: String
status: String
updated_at: Timestamp
}

Transaction Behavior​

All mutations within a single GraphQL request execute in a transaction:

mutation ComplexTransaction {
# All operations succeed or fail together
update_inventory: update_products(
filter: { id: { eq: 100 } }
data: { stock: 45 }
) {
affected_rows
}

create_order: insert_orders(data: {
customer_id: 50
product_id: 100
quantity: 5
}) {
id
}

update_customer: update_customers(
filter: { id: { eq: 50 } }
data: { last_order_date: "2024-01-15" }
) {
affected_rows
}
}

The mutations can be executed only in one data source context.

Auto-Generated Values​

Sequences​

For fields with sequences:

type orders @table(name: "orders") {
id: BigInt! @pk @default(sequence: "orders_id_seq")
order_number: Int! @default(sequence: "order_number_seq")
}

The ID fields are auto-populated during insert.

Default Values​

Fields with default values are optional in mutations:

type customers @table(name: "customers") {
status: String! @default(value: "pending")
created_at: Timestamp! @default(insert_exp: "NOW()", update_exp: "objects.created_at")
}

Semantic Search and Embeddings​

For data objects with embeddings, use the summary parameter to generate vector representations during insert or update mutations:

mutation {
insert_documents(
data: {
title: "GraphQL Overview"
content: "GraphQL is a query language for APIs."
}
summary: "GraphQL is a query language for APIs."
) {
id
}
update_documents(
filter: { id: { eq: 1 } }
data: { content: "Updated content" }
summary: "Updated summary"
) {
success
message
affected_rows
}
}