Skip to content

Record Wrappers (Document, Vertex, Edge)

The Python API provides Pythonic wrapper classes for database records: Document, Vertex, and Edge. These wrappers hide the underlying Java implementation and provide a clean Python interface.

Overview

Class Purpose Usage
Document Base wrapper for all records (documents, vertices, edges) Property access, modification, deletion
Vertex Wrapper for graph vertices Creating edges, traversal
Edge Wrapper for graph edges Accessing source/target vertices

Document Wrapper

The Document class is the base wrapper for all record types. Use it for documents and as the base class for Vertex and Edge.

Creating Documents

import arcadedb_embedded as arcadedb
from arcadedb_embedded.graph import Document, Vertex, Edge

with arcadedb.create_database("./mydb") as db:
    # Schema operations are auto-transactional
    db.schema.create_document_type("Note")

    # Create a document
    with db.transaction():
        doc = db.new_document("Note")
        doc.set("title", "My Note")
        doc.set("content", "Important information")
        doc.save()

        # Get the RID for later retrieval
        doc_id = str(doc.get_identity())
        print(f"Created document: {doc_id}")

Properties and Methods

set(key, value) -> Document

Set a property on the document. Returns self for chaining.

doc.set("name", "Alice")
doc.set("age", 30)
doc.set("active", True)

# Chaining
doc.set("name", "Bob").set("age", 25).save()

get(key) -> Any

Get a property value.

name = doc.get("name")
age = doc.get("age")
email = doc.get("email")               # Returns None if not found
email = doc.get("email") or "unknown"  # Use default pattern

get_property_names() -> List[str]

Get all property names on the document.

props = doc.get_property_names()
print(f"Properties: {props}")
# Output: Properties: ['name', 'age', 'active']

has_property(key) -> bool

Check if a property exists.

if doc.has_property("email"):
    email = doc.get("email")
else:
    print("Email not set")

save() -> Document

Save changes to the database. Returns self.

doc.set("name", "Updated Name")
doc.save()  # Persists changes

delete() -> None

Delete the document from the database.

⚠️ Important Limitation: Only works on objects from lookup_by_rid() or newly created objects, not on query results. Use SQL DELETE for query results.

# ✅ Works on fresh lookup
with db.transaction():
    doc = db.lookup_by_rid("#1:0")
    doc.delete()

# ✅ Works on newly created
with db.transaction():
    doc = db.new_document("Note")
    doc.set("title", "Test")
    doc.save()
    doc.delete()

# ❌ Doesn't work on query results
results = db.query("sql", "SELECT FROM Note WHERE title = 'Test'")
for doc in results:
    doc.delete()  # No-op!

# ✅ Use SQL DELETE instead
with db.transaction():
    db.command("sql", "DELETE FROM Note WHERE title = 'Test'")

to_dict() -> dict

Convert the document to a Python dictionary of its properties (metadata like RID/type is not included). Use get_rid() for the record ID if needed.

doc_dict = doc.to_dict()
print(doc_dict)
# Output: {'name': 'Alice', 'age': 30, 'active': True}

rid = doc.get_rid()

get_identity() -> str

Get the Record ID (RID) of the document.

rid = doc.get_identity()
print(rid)  # Output: #1:0

get_type_name() -> str

Get the type name of the document.

type_name = doc.get_type_name()
print(type_name)  # Output: Note

modify() -> Document

Get a mutable version of the document. Useful for immutable query results.

# Query results are iterators and often immutable
results = db.query("sql", "SELECT FROM Note LIMIT 1")
immutable_doc = next(iter(results))

# Get mutable version for modification
with db.transaction():
    mutable_doc = immutable_doc.modify()
    mutable_doc.set("updated", True).save()

wrap(java_object) -> Document

Static method to wrap Java objects as Python wrappers. Automatically detects type.

from arcadedb_embedded.graph import Document

# Wrap Java object and automatically detect type
wrapped = Document.wrap(java_object)
# Returns: Document, Vertex, or Edge depending on actual type

Vertex Wrapper

The Vertex class extends Document with graph-specific methods for creating and traversing edges.

Creating Vertices

# Schema operations are auto-transactional
db.schema.create_vertex_type("Person")

with db.transaction():
    alice = db.new_vertex("Person")
    alice.set("name", "Alice")
    alice.set("age", 30)
    alice.save()

    print(f"Created vertex: {alice.get_identity()}")

Graph Methods

new_edge(edge_type, target_vertex, **properties) -> Edge

Create an edge from this vertex to another vertex.

with db.transaction():
    alice = db.new_vertex("Person").set("name", "Alice").save()
    bob = db.new_vertex("Person").set("name", "Bob").save()

    # Create edge
    edge = alice.new_edge("Knows", bob)
    edge.set("since", 2020)
    edge.save()

get_out_edges(*labels) -> List[Edge]

Get outgoing edges from this vertex, optionally filtered by label.

# All outgoing edges
outgoing = alice.get_out_edges()
for edge in outgoing:
    target = edge.get_in()
    print(f"Alice -> {target.get('name')}")

# Filter by edge type
knows = alice.get_out_edges("Knows")
assert all(e.get_in().get("name") in {"Bob", "Carol"} for e in knows)

get_in_edges(*labels) -> List[Edge]

Get incoming edges to this vertex, optionally filtered by label.

incoming = alice.get_in_edges()
for edge in incoming:
    source = edge.get_out()
    print(f"{source.get('name')} -> Alice")

# Filter by edge type
knows_in = alice.get_in_edges("Knows")

get_both_edges(*labels) -> List[Edge]

Get both incoming and outgoing edges, optionally filtered by label.

all_edges = alice.get_both_edges()
print(f"Degree: {len(all_edges)}")

knows_edges = alice.get_both_edges("Knows")

Edge Wrapper

The Edge class represents a connection between vertices with optional properties.

Edge Properties

Edges have the same property methods as documents:

edge = alice.new_edge("Knows", bob)
edge.set("since", 2020)
edge.set("strength", 0.9)
edge.save()

print(edge.get("since"))  # Output: 2020
edge.get_property_names()  # ['since', 'strength']

Graph Methods

get_in() -> Vertex

Get the incoming (destination) vertex of the edge.

source = edge.get_in()
print(f"Source: {source.get('name')}")

get_out() -> Vertex

Get the outgoing (source) vertex of the edge.

target = edge.get_out()
print(f"Target: {target.get('name')}")

Best Practices

1. Always Save After Set

# ❌ Bad - changes not persisted
with db.transaction():
    doc.set("name", "Alice")
# No save!

# ✅ Good
with db.transaction():
    doc.set("name", "Alice")
    doc.save()

2. Use Fresh Lookups for Delete (Python-first)

# ❌ Don't delete query results directly
results = db.query("sql", "SELECT FROM Note")
for doc in results:
    doc.delete()  # No-op

# ✅ Pythonic single-record delete by RID
with db.transaction():
    doc = db.lookup_by_rid("#1:0")
    doc.delete()

# ✅ Convert query results to RIDs, then delete via lookup
with db.transaction():
    rids = [doc.get_rid() for doc in db.query("sql", "SELECT FROM Note WHERE flagged = true")]
    for rid in rids:
        db.lookup_by_rid(rid).delete()

# ✅ Set-based delete (when you really want bulk SQL)
with db.transaction():
    db.command("sql", "DELETE FROM Note WHERE flagged = true")

3. Create Indexes for Frequent Lookups

db.schema.create_index("Person", ["name"], unique=False)
# SQL DDL is also supported, but the Schema API is preferred in embedded mode.

4. Chain Methods for Brevity

# Chaining
with db.transaction():
    doc = db.new_document("Note") \
        .set("title", "My Note") \
        .set("content", "Content") \
        .save()