Data objects
In this guide, you’ll see how to use driver API methods and stateful objects to programmatically manipulate data in a database using one of the TypeDB drivers. This page assumes you’ve already followed instructions from the Insert query page.
Understanding data objects
Data objects represent data instances in a TypeDB database. Driver APIs provide a set of methods to programmatically manipulate these objects.
Get data objects
To manipulate data with driver API methods, you need to get a stateful object that represents a data instance in the database.
To get a data object from a TypeDB database, you can use a TypeQL Get query or one of the driver API methods.
Query for data objects
Send a Get query with a pattern to retrieve data
and process the response to get data objects.
For example, to get all instances of the user
type, send the following Get query:
match
$u isa user;
get $u;
Get all instances of a type
Use a type object to retrieve all data objects of that type.
For example, let’s get a stateful object of the user
entity type, and then get all instances of data as data objects:
-
Rust
-
Python
-
Node.js
-
Java
-
C#
-
C++
-
C
let users = user_type.get_instances(&tx, Transitivity::Transitive)?;
For more information, see the ConceptManager class methods.
users = user_type.get_instances(tx)
For more information, see the ConceptManager class methods.
let users = userType.getInstances(tx);
For more information, see the ConceptManager class methods.
Stream<? extends Entity> users = userType.getInstances(tx);
For more information, see the ConceptManager class methods.
IEnumerable<IThing> users = userType.GetInstances(tx);
For more information, see the IConceptManager class methods.
TypeDB::ConceptIterable<TypeDB::Entity> users = userType -> getInstances(tx);
For more information, see the ConceptManager class methods.
ConceptIterator* users = entity_type_get_instances(tx, userType, Explicit);
For more information, see the Concepts section functions.
Traverse data objects
The Data class has methods to traverse data objects by retrieving all owned attributes,
all relations played in and respective roles.
For example, let’s get data objects of all attributes owned by the instance,
represented by the data object in the user
variable:
-
Rust
-
Python
-
Node.js
-
Java
-
C#
-
C++
-
C
let attributes = user?.get_has(&tx, vec![], vec![])?;
For more information, see the Data class methods.
attributes = user.get_has(tx)
For more information, see the Data class methods.
let attributes = user.getHas(tx);
For more information, see the Data class methods.
Stream<? extends Attribute> attributes = user.getHas(tx, annotations);
For more information, see the Data class methods.
IEnumerable<IAttribute> attributes = user.GetHas(tx);
For more information, see the Data class methods.
TypeDB::ConceptIterable<TypeDB::Attribute> attributes = user.get()->getHas(tx);
For more information, see the Data class methods.
const struct Concept *const attribute_types[] = {NULL};
const struct Annotation* emptyAnnotations[] = {NULL};
ConceptIterator* attributes = thing_get_has(tx, user, attribute_types, emptyAnnotations);
For more information, see the Concepts section functions.
Create data objects
To add a new instance of a type, use the create method of a type object:
-
Rust
-
Python
-
Node.js
-
Java
-
C#
-
C++
-
C
let new_user =
tx.concept().get_entity_type("user".to_owned()).resolve()?.unwrap().create(&tx).resolve()?;
For more information, see the EntityType class methods.
new_user = tx.concepts.get_entity_type("user").resolve().create(tx).resolve()
For more information, see the EntityType class methods.
let newUser = await (await tx.concepts.getEntityType("user")).create(tx);
For more information, see the EntityType class methods.
Entity new_user = tx.concepts().getEntityType("user").resolve().create(tx).resolve();
For more information, see the EntityType class methods.
IEntity newUser = tx.Concepts.GetEntityType("user").Resolve()!.Create(tx).Resolve()!;
For more information, see the IEntityType class methods.
std::unique_ptr<TypeDB::Entity> newUser = tx.concepts.getEntityType("user").get().get()->create(tx).get();
For more information, see the EntityType class methods.
Concept* newUser = concept_promise_resolve(entity_type_create(tx, concept_promise_resolve(concepts_get_entity_type(tx, "user"))));
For more information, see the Concepts section functions.
Data manipulation
Data object has a limited number of methods to manipulate data: you can delete the data instance and assign/unassign ownership of an attribute. For relations, you can add or remove players for their roles.
-
Rust
-
Python
-
Node.js
-
Java
-
C#
-
C++
-
C
let _ = new_user.delete(&tx).resolve();
For more information, see the EntityType class methods.
new_user.delete(tx)
For more information, see the EntityType class methods.
await newUser.delete(tx);
For more information, see the EntityType class methods.
new_user.delete(tx).resolve();
For more information, see the EntityType class methods.
newUser.Delete(tx).Resolve();
For more information, see the IEntityType class methods.
newUser.get()->deleteThing(tx).get();
For more information, see the EntityType class methods.
void_promise_resolve(thing_delete(tx, newUser));
For more information, see the Concepts section functions.
Full example
See below a comprehensive example of programmatic data manipulation.
In this example we
retrieve the user
type, get all its instances, iterate through every user,
retrieve all owned attributes for every user, and print values of these attributes.
Then we add a new instance of the user
entity type.
-
Rust
-
Python
-
Node.js
-
Java
-
C#
-
C++
-
C
let databases = DatabaseManager::new(driver);
let db = databases.get(DB_NAME)?;
{
let session = Session::new(db, SessionType::Data)?;
{
let tx = session.transaction(TransactionType::Write)?;
let user_type = tx.concept().get_entity_type("user".to_owned()).resolve()?.unwrap();
let users = user_type.get_instances(&tx, Transitivity::Transitive)?;
for user in users {
let user = user?;
println!("User:");
let attributes = user.get_has(&tx, vec![], vec![])?;
for attribute in attributes {
let attribute = attribute?;
let value = match attribute.value {
Value::String(value) => value,
Value::Long(value) => value.to_string(),
Value::Double(value) => value.to_string(),
Value::DateTime(value) => value.to_string(),
Value::Boolean(value) => value.to_string(),
};
println!(" {}: {}", attribute.type_.label, value)
}
}
let new_user =
tx.concept().get_entity_type("user".to_owned()).resolve()?.unwrap().create(&tx).resolve()?;
let _ = new_user.delete(&tx).resolve();
}
}
For more information, see the Data class methods.
with driver.session(DB_NAME, SessionType.DATA) as session:
with session.transaction(TransactionType.WRITE) as tx:
user_type = tx.concepts.get_entity_type("user").resolve()
users = user_type.get_instances(tx)
for user in users:
attributes = user.get_has(tx)
print("User:")
for attribute in attributes:
print(f" {attribute.get_type().get_label().name} : {attribute.get_value()}")
new_user = tx.concepts.get_entity_type("user").resolve().create(tx).resolve()
new_user.delete(tx)
tx.commit()
For more information, see the Data class methods.
try {
session = await driver.session(DB_NAME, SessionType.DATA);
try {
tx = await session.transaction(TransactionType.WRITE);
let userType = await tx.concepts.getEntityType("user");
let users = userType.getInstances(tx);
for await (const user of users) {
let attributes = user.getHas(tx);
console.log("User:");
for await (const attribute of attributes) {
console.log(" " + attribute.type.label.toString() + ": " + attribute.value.toString());
}
}
let newUser = await (await tx.concepts.getEntityType("user")).create(tx);
await newUser.delete(tx);
await tx.commit();
}
finally {if (tx.isOpen()) {await tx.close()};}
}
finally {await session?.close();}
For more information, see the Data class methods.
try (TypeDBSession session = driver.session(DB_NAME, TypeDBSession.Type.DATA)) {
try (TypeDBTransaction tx = session.transaction(TypeDBTransaction.Type.WRITE)) {
Set<ThingType.Annotation> annotations = Collections.emptySet();
EntityType userType = tx.concepts().getEntityType("user").resolve();
userType.getInstances(tx).forEach(user -> {
System.out.println("User");
Stream<? extends Attribute> attributes = user.getHas(tx, annotations);
attributes.forEach(attribute ->
System.out.println(attribute.getType().getLabel().toString()+ ": " + attribute.getValue().toString())
);
});
Entity new_user = tx.concepts().getEntityType("user").resolve().create(tx).resolve();
new_user.delete(tx).resolve();
tx.commit();
}
}
For more information, see the Data class methods.
using (ITypeDBSession session = driver.Session(DB_NAME, SessionType.Data)) {
using (ITypeDBTransaction tx = session.Transaction(TransactionType.Write)) {
IEntityType userType = tx.Concepts.GetEntityType("user").Resolve()!;
IEnumerable<IThing> users = userType.GetInstances(tx);
foreach (IThing user in users) {
IEnumerable<IAttribute> attributes = user.GetHas(tx);
foreach (IAttribute attribute in attributes) {
Console.WriteLine(" " + attribute.Type.Label + ": " + attribute.Value.AsString());
}
}
IEntity newUser = tx.Concepts.GetEntityType("user").Resolve()!.Create(tx).Resolve()!;
newUser.Delete(tx).Resolve();
tx.Commit();
}
}
For more information, see the Data section methods.
TypeDB::Session session = driver.session(DB_NAME, TypeDB::SessionType::DATA, options);
{
TypeDB::Transaction tx = session.transaction(TypeDB::TransactionType::WRITE, options);
std::unique_ptr<TypeDB::EntityType> userType = tx.concepts.getEntityType("user").get();
TypeDB::ConceptIterable<TypeDB::Entity> users = userType -> getInstances(tx);
for (std::unique_ptr<TypeDB::Entity>& user : users) {
TypeDB::ConceptIterable<TypeDB::Attribute> attributes = user.get()->getHas(tx);
std::cout << "User: " << std::endl;
for (std::unique_ptr<TypeDB::Attribute>& attribute : attributes) {
std::cout << " " << attribute.get()->getType().get()->getLabel() << ": " << attribute.get()->getValue().get()->asString() << std::endl;
}
}
std::unique_ptr<TypeDB::Entity> newUser = tx.concepts.getEntityType("user").get().get()->create(tx).get();
newUser.get()->deleteThing(tx).get();
tx.commit();
}
For more information, see the Data class methods.
session = session_new(databaseManager, DB_NAME, Schema, opts);
tx = transaction_new(session, Write, opts);
if ((tx == NULL) || FAILED()) {
handle_error("Transaction failed to start.");
goto cleanup;
}
Concept* userType = concept_promise_resolve(concepts_get_entity_type(tx, "user"));
ConceptIterator* users = entity_type_get_instances(tx, userType, Explicit);
Concept* user;
while ((user = concept_iterator_next(users)) != NULL) {
printf("%s \n", "User:");
const struct Concept *const attribute_types[] = {NULL};
const struct Annotation* emptyAnnotations[] = {NULL};
ConceptIterator* attributes = thing_get_has(tx, user, attribute_types, emptyAnnotations);
Concept* attribute;
while ((attribute = concept_iterator_next(attributes)) != NULL) {
printf("%s: %s\n", thing_type_get_label(attribute_get_type(attribute)), value_get_string(attribute_get_value(attribute)));
}
}
Concept* newUser = concept_promise_resolve(entity_type_create(tx, concept_promise_resolve(concepts_get_entity_type(tx, "user"))));
void_promise_resolve(thing_delete(tx, newUser));
void_promise_resolve(transaction_commit(tx));
if (FAILED()) {
handle_error("Transaction commit failed.");
goto cleanup;
}
session_close(session);
For more information, see the Concepts section functions.