Inserting data
This page explains how to insert data in a TypeDB database.
Understanding insert pipeline stages
An insert stage is used to insert data into a database.
It is usually executed in write
transactions.
It can be used as a single query, meaning the insertion will occur exactly once.
Alternatively, it can be a stage in a pipeline, potentially with multiple input rows from the preceding stage (e.g., a match
stage).
Refer to the Insert stage page for a detailed explanation and additional examples.
Sending insert pipelines
The examples below can be combined with the following schema file. A part of this file is defined in the respective definition guides. See the schema.tqlschema.tql
|
Insert an instance
To insert data, open a write
transaction.
This allows you to read and write data to your database while keeping the schema secure.
Every insertion begins with an insert
.
Similar to type definition, multiple statements can be combined to insert multiple instances and establish connections between them.
To insert a type instance (an entity, a relation, or an attribute), use the isa
keyword:
insert $u isa user;
All data inserted into a database is verified against the schema constraints (e.g., existence of supertypes, traits, annotations, etc.).
Some verifications occur during query execution ("operation time"), while others wait until commit for your convenience. For example, the above query works with a minimal schema like this:
define entity user;
However, if the full example schema is used, a key attribute is required for every inserted user, so it is impossible to use this insert query only.
Insert an instance with ownership
To insert both an entity and an owned attribute, combine isa
and has
statements in a single expression:
insert
$u isa user, has username "User";
Why is username a key?
If you explore the schema, you’ll see that user
s inherit an abstract key attribute id
from content
.
While abstract attributes cannot have instances, this definition states that any id
owned by a content
is a key attribute.
At the same time, username
is an attribute with a supertype id
, meaning it is an id
.
It is also inherited by user
s from profile
.
Thus, a username
can serve as a user
's key: a unique and singular identifier!
Insert a relation
Similarly, multiple users can be inserted and connected through a relation.
To insert a relation, use the links
keyword, specifying roleplayers with the (role: $var)
format.
The expression can also be simplified to an anonymous relation with a short declaration (see the full syntax in the next example):
insert
$a isa user, has username "Alice", has email "alice@typedb.com";
$b isa user, has username "Bob", has email "bob@typedb.com";
(friend: $a, friend: $b) isa friendship;
Inserting data based on a match
Using pipelines, you can match and modify your data in multiple stages, creating complex queries and automations.
A simple example is an insert
stage based on results of a match
stage.
Suppose we send the following query with an insert stage following a match stage:
match
$u isa user, has username "Bob";
insert
$new-u isa user, has username "Charlie", has email "charlie@typedb.com";
$f isa friendship, links (friend: $u, friend: $new-u);
With the data inserted earlier on this page, we should match only one user with the username "Bob". This results in inserting one new user and one relevant relation. If multiple matches are made by the match clause, the insert clause executes for each match (in our case, this would lead to an error due to a duplicate key "Charlie," but it might be useful in other scenarios). If no matches are made, nothing is inserted.
Refer to Data pipelines for more information.
Response interpretation
An insert stage returns all concepts inserted into the database as a stream of concept rows. A collected stream of concept rows can be interpreted as a table with a header containing variables and rows with respective concept answers for each variable. This lets you verify if the result meets your expectations.
For example, the following is a snapshot of a TypeDB Console’s response to the previous query (iid
s may vary):
------------
$f | iid 0x1f00020000000000000001 isa friendship
$new-u | iid 0x1e00030000000000000003 isa user
$u | iid 0x1e00030000000000000000 isa user
------------
Preserving or reverting changes
Do not forget to commit your transaction to preserve the changes. As mentioned earlier, some data constraints are only validated upon commit. This means you might discover inconsistencies in your data during the commit process, and the commit will be rejected.
While most validations occur during operation time to keep data synchronized, commit-time validations are necessary to allow flexible data modifications. For example, validating inserted data against cardinality during operation time could block modifications entirely.
If you want to abort your changes, simply close the transaction or perform a rollback. Refer to Transactions for more details.
Having troubles?
Refer to the Debugging queries page for common debugging tips.