Insert
Add new nodes and edges to the graph.
The insert operation adds new nodes and edges to the graph. Inserts are validated against the schema at commit time: every required property must be present, types must match, and constraint annotations are enforced.
Inserting nodes
Use insert TypeName { ... } inside a named query to add a node:
query add_person($name: String, $age: I32) {
insert Person { name: $name, age: $age }
}Run it from the CLI:
omnigraph change ./my-graph \
--query mutations.gq \
--name add_person \
--params '{"name": "Alice", "age": 30}'Or via the HTTP API:
curl -X POST http://localhost:4000/change \
-H "Content-Type: application/json" \
-d '{
"uri": "./my-graph",
"query": "mutations.gq",
"name": "add_person",
"params": {"name": "Alice", "age": 30}
}'Nullable properties
Properties marked with ? in the schema can be omitted from the insert. Omitted nullable properties default to null:
node Person {
name: String @key
age: I32?
bio: String?
}query add_person($name: String) {
insert Person { name: $name }
}This inserts a Person with age and bio set to null.
Inserting edges
Edges connect two existing nodes. You reference the source and destination by their @key values:
query add_edge($person: String, $company: String) {
insert WorksAt { src: $person, dst: $company }
}omnigraph change ./my-graph \
--query mutations.gq \
--name add_edge \
--params '{"person": "Alice", "company": "Acme"}'If the edge type has properties, include them in the insert:
query add_knows($a: String, $b: String, $since: Date) {
insert Knows { src: $a, dst: $b, since: $since }
}Both the source and destination nodes must already exist. If either is missing, the insert fails with a referential integrity error.
Upsert behavior for @key types
When you insert a node whose type has a @key property, and a node with that key value already exists, Omnigraph performs an upsert: the existing node is updated with the new property values instead of creating a duplicate.
node Person {
name: String @key
age: I32?
}query upsert_person($name: String, $age: I32) {
insert Person { name: $name, age: $age }
}If a Person with name = "Alice" already exists, this updates her age rather than inserting a second row.
Constraint validation
Inserts are checked against every constraint declared in the schema:
| Constraint | Behavior on insert |
|---|---|
@key | Upserts if a matching key already exists |
@unique | Rejects the insert if a duplicate value exists |
@range | Rejects the insert if the value is outside the declared range |
@check | Rejects the insert if the check expression evaluates to false |
| Required properties | Rejects the insert if a non-nullable property is missing |
If any constraint fails, the entire transaction is rolled back and no data is written.
Bulk inserts with JSONL
For loading large volumes of data, use the load subcommand with a JSONL file instead of individual insert mutations:
omnigraph load ./my-graph --data data.jsonlSee the Quick Start for the JSONL format.
Blob properties
Node types with Blob properties accept two value formats in inserts.
Base64-encoded inline data:
query add_photo($slug: String) {
insert Photo {
slug: $slug,
image: "base64:iVBORw0KGgo...",
}
}URI reference (S3 or local path):
query add_photo_from_s3($slug: String) {
insert Photo {
slug: $slug,
image: "s3://my-bucket/photos/sunset.jpg",
}
}Blob properties appear as null in normal query projections. To read blob bytes, use the dedicated blob read API rather than a standard return projection.