Download notebook · View source · Open in Colab
Work with Entities
Entities represent application concepts such as people, ingredients, products, and events. Each entity belongs to a class and stores named properties. This example adds an ingredient, queries its properties, updates it, and deletes it.
The examples require Python 3.10 or later, an ApertureDB connection profile or environment credentials, and permission to create, read, update, and delete objects. A unique documentation_run property separates the example data from other records. Cleanup uses that value, so keep the setup variables available until cleanup completes.
Connect to the database
The examples require a running database and configured client credentials. The quick start guide describes the setup.
# Install the required client packages if needed
%pip install --quiet "aperturedb==0.5.1"
Note: you may need to restart the kernel to use updated packages.
from aperturedb.CommonLibrary import create_connector
# Create the connector for ApertureDB
client = create_connector()
import uuid
documentation_run = uuid.uuid4().hex
ingredient_class = "CookbookIngredient_" + documentation_run
connection_class = "CookbookIngredientLink_" + documentation_run
def checked_query(query, input_blobs=None):
response, output_blobs = client.query(query, input_blobs or [])
assert isinstance(response, list) and len(response) == len(query), response
for command in response:
result = next(iter(command.values()))
assert result.get("status") == 0, response
return response, output_blobs
# Simple query to see how the database is doing
# https://docs.aperturedata.io/query_language/Reference/db_commands/GetStatus
query = [{
"GetStatus": {
}
}]
# Execute the query to get back a JSON response for GetStatus
response, blobs = checked_query(query)
client.print_last_response()
[
{
"GetStatus": {
"info": "OK",
"status": 0,
"system": "ApertureDB",
"version": "0.19.15"
}
}
]
Create or Add an Ingredient to ApertureDB
AddEntity creates an ingredient with properties describing its name and category. The request includes this run's identifier so later queries select the same record.
The Python SDK loaders handle bulk ingestion.
query = [{
"AddEntity": {
"class": ingredient_class, # Every entity belongs to a class, in this case Ingredient
"properties": {
'documentation_run': documentation_run, # You can define as many key, value properties per entity, as needed
"name": "butter", # The data type for "name" property of an Ingredient will now always be of the type "string".
"macronutrient": "fat",
"subgroup": "dairy",
"category": "vegetarian"
},
"if_not_found": ['all', ['$name', '==', 'butter'], ['$documentation_run', '==', documentation_run]]
}
}]
response, blobs = checked_query(query)
client.print_last_response()
[
{
"AddEntity": {
"status": 0
}
}
]
Read or Query properties of the added Ingredient
FindEntity selects the ingredient by its properties. The response includes the stored property values.
query = [{
"FindEntity": {
"with_class": ingredient_class, # Every entity belongs to a class, in this case Ingredient
"constraints": ['all', ['all', ['$name', '==', 'butter'], ['$subgroup', '==', 'dairy']], ['$documentation_run', '==', documentation_run]],
"results": {
"all_properties": True
}
}
}]
response, blobs = checked_query(query)
client.print_last_response()
assert response[0]["FindEntity"]["returned"] == 1
assert response[0]["FindEntity"]["entities"][0]["name"] == "butter"
[
{
"FindEntity": {
"entities": [
{
"_uniqueid": "8.0.80",
"category": "vegetarian",
"documentation_run": "092ae3a1de2c490ea3791ead48c53066",
"macronutrient": "fat",
"name": "butter",
"subgroup": "dairy"
}
],
"returned": 1,
"status": 0
}
}
]
Update properties of the Ingredient already in ApertureDB
UpdateEntity changes existing property values or adds properties to matching entities.
query = [{
"UpdateEntity": {
"with_class": ingredient_class,
"properties": {
"micronutrient": "omega-3" # property will get added if missing or the value will be updated
},
"constraints": ['all', ['$name', '==', 'butter'], ['$documentation_run', '==', documentation_run]],
}
}]
response, blobs = checked_query(query)
client.print_last_response()
[
{
"UpdateEntity": {
"count": 1,
"status": 0
}
}
]
query = [{
"FindEntity": {
"with_class": ingredient_class,
"constraints": ['all', ['$name', '==', 'butter'], ['$documentation_run', '==', documentation_run]],
"results": {
"all_properties": True
}
}
}]
response, blobs = checked_query(query)
client.print_last_response()
assert response[0]["FindEntity"]["entities"][0]["micronutrient"] == "omega-3"
[
{
"FindEntity": {
"entities": [
{
"_uniqueid": "8.0.80",
"category": "vegetarian",
"documentation_run": "092ae3a1de2c490ea3791ead48c53066",
"macronutrient": "fat",
"micronutrient": "omega-3",
"name": "butter",
"subgroup": "dairy"
}
],
"returned": 1,
"status": 0
}
}
]
Delete the ingredient
DeleteEntity removes the ingredient selected by its properties and this run's identifier.
query = [{
"DeleteEntity": {
"with_class": ingredient_class,
"constraints": ['all', ['$name', '==', 'butter'], ['$documentation_run', '==', documentation_run]]
}
}]
response, blobs = checked_query(query)
client.print_last_response()
[
{
"DeleteEntity": {
"count": 1,
"status": 0
}
}
]
Verify deletion
After deletion, FindEntity returns no matching ingredient.
query = [{
"FindEntity": {
"with_class": ingredient_class,
"constraints": ['all', ['$name', '==', 'butter'], ['$documentation_run', '==', documentation_run]],
"results": {
"all_properties": True
}
}
}]
response, blobs = checked_query(query)
client.print_last_response()
assert response[0]["FindEntity"]["returned"] == 0
[
{
"FindEntity": {
"returned": 0,
"status": 0
}
}
]
What's next?