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.
save() -> Document¶
Save changes to the database. Returns self.
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.
get_type_name() -> str¶
Get the type name of the document.
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.
get_out() -> Vertex¶
Get the outgoing (source) vertex of the edge.
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.