Results API¶
The ResultSet and Result classes provide Python-friendly interfaces for working with query results from ArcadeDB. They handle iteration, property access, and type conversion automatically.
Using Context Managers
For automatic resource cleanup, prefer using context managers:
with arcadedb.open_database("./mydb") as db:
result_set = db.query("sql", "SELECT FROM Person WHERE age > 25")
for result in result_set:
print(result.get("name"))
# Database automatically closed
db.close() for clarity, but context managers are recommended in production.
Overview¶
When you execute a query, ArcadeDB returns a ResultSet that can be iterated to access individual Result objects. Each Result represents one row/record from your query.
Key Features:
- Pythonic iteration: Use
forloops or iterators - Property access: Get values by property name
- Type conversion: Automatic conversion from Java to Python types
- Multiple access patterns: Dict-like access, JSON export, direct properties
ResultSet Class¶
Iterable wrapper for query results. ResultSet is a Python iterator: iterate it with a
for loop, next(), or materialize it with helpers like to_list(), first(), and
one().
Creation¶
ResultSet objects are returned by query operations:
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./mydb")
# query() returns ResultSet
result_set = db.query("sql", "SELECT FROM Person WHERE age > 25")
# command() also returns ResultSet for SELECT queries
result_set = db.command("sql", "SELECT * FROM Person LIMIT 10")
Iteration¶
ResultSet implements the Python iterator protocol (__iter__/__next__), so each
iteration yields a Result. Iteration consumes the underlying result set.
# Using for loop (most Pythonic)
for result in result_set:
name = result.get("name")
age = result.get("age")
print(f"{name}: {age}")
# As iterator
result_set = db.query("sql", "SELECT FROM Product")
results = list(result_set) # Convert to list of Result objects
# Or use the built-in next()
result_set = db.query("sql", "SELECT FROM Document")
first = next(result_set) # Raises StopIteration when exhausted
to_list(convert_types: bool = True) -> List[Dict[str, Any]]¶
Convert all results to a list of dictionaries.
Parameters:
convert_types(bool): Convert Java types to Python types (default:True)
Returns:
List[Dict[str, Any]]: List of dictionaries with result data
Example:
results = db.query("sql", "SELECT FROM User LIMIT 10")
users = results.to_list()
print(users[0])
# {'name': 'Alice', 'age': 30, 'email': 'alice@example.com'}
iter_dicts(convert_types: bool = True) -> Iterator[Dict[str, Any]]¶
Iterate results as dictionaries.
Parameters:
convert_types(bool): Convert Java types to Python types (default:True)
Yields:
- Result rows as dictionaries
to_dataframe(convert_types: bool = True)¶
Convert results to a pandas DataFrame. Requires pandas to be installed.
Parameters:
convert_types(bool): Convert Java types to Python types (default:True)
Returns:
- pandas DataFrame
Raises:
ImportError: If pandas is not installed
Example:
iter_chunks(size: int = 1000, convert_types: bool = True) -> Iterator[List[Dict[str, Any]]]¶
Iterate results in chunks for memory-efficient processing.
Parameters:
size(int): Chunk size (default:1000)convert_types(bool): Convert Java types to Python types (default:True)
Yields:
- Lists of dictionaries (up to
sizeelements each)
Example:
results = db.query("sql", "SELECT FROM User")
for chunk in results.iter_chunks(size=1000):
process_batch(chunk) # chunk is a list of dicts
count() -> int¶
Count the remaining results without building a list.
Returns:
int: Number of remaining results
Note: This consumes the remaining rows from the current result set. After calling
count(), the iterator is exhausted.
Example:
first() -> Optional[Result]¶
Get the first result, or None if there are no results.
Returns:
ResultorNone
Example:
one() -> Result¶
Get a single result, raising ValueError if there is not exactly one.
Returns:
Result: The single result
Raises:
ValueError: If zero or multiple results
Example:
user = db.query(
"sql",
"SELECT FROM User WHERE email = ?",
"alice@example.com",
).one()
print(user.get("name"))
Result Class¶
Represents a single result row/record from a query.
Creation¶
Result objects are created automatically when iterating a ResultSet:
result_set = db.query("sql", "SELECT FROM Person")
# Each iteration gives you a Result
for result in result_set:
# result is a Result object
pass
get(name: str, convert_types: bool = True) -> Any¶
Get the value of a property by name.
Parameters:
name(str): Property nameconvert_types(bool): Convert Java types to Python types (default:True)
Returns:
Any: Property value (type depends on the data), orNoneif property doesn't exist- Automatically converts Java types to Python types
- Java
Boolean→ Pythonbool - Java
Integer/Long→ Pythonint - Java
Float/Double→ Pythonfloat - Java
String→ Pythonstr - Java collections → Python lists/dicts
Example:
result_set = db.query("sql", "SELECT name, age, active FROM User")
for result in result_set:
name = result.get("name") # str
age = result.get("age") # int
active = result.get("active") # bool (converted from Java Boolean)
print(f"{name} is {age} years old, active: {active}")
# Handle optional properties with fallback
email = result.get("email") or "unknown@example.com"
print(f"Email: {email}")
has_property(name: str) -> bool¶
Check if a property exists in the result.
Parameters:
name(str): Property name to check
Returns:
bool:Trueif property exists,Falseotherwise
Example:
result_set = db.query("sql", "SELECT * FROM Person")
for result in result_set:
if result.has_property("email"):
email = result.get("email")
print(f"Email: {email}")
else:
print("No email address")
get_property_names() -> List[str]¶
Get list of all property names in the result.
Returns:
List[str]: List of property names
Example:
result_set = db.query("sql", "SELECT * FROM Document LIMIT 1")
for result in result_set:
properties = result.get_property_names()
print(f"Properties: {', '.join(properties)}")
for prop in properties:
value = result.get(prop)
print(f" {prop}: {value}")
get_rid() -> Optional[str]¶
Get the Record ID (RID) of the result, if available.
Returns:
str(e.g."#10:5") orNone
Example:
to_dict(convert_types: bool = True) -> Dict[str, Any]¶
Convert the result to a Python dictionary.
Parameters:
convert_types(bool): Convert Java types to Python types (default:True)
Returns:
Dict[str, Any]: Dictionary with property names as keys
Example:
result_set = db.query("sql", "SELECT name, age, city FROM Person")
# Convert all results to list of dicts
people = [result.to_dict() for result in result_set]
for person in people:
print(person)
# {'name': 'Alice', 'age': 30, 'city': 'NYC'}
Use Cases:
- Converting to pandas DataFrame
- Serialization to JSON (via
json.dumps()) - Passing data to other libraries
- Debugging/inspection
Performance note: to_dict() eagerly converts the current row to Python data.
That is convenient for small projections and interop, but repeated to_dict() calls
across a large result set will allocate Python objects for every returned property.
For large scans, prefer iterating and reading only the fields you need with get().
to_json() -> str¶
Convert the result to a JSON string.
Returns:
str: JSON representation of the result
Example:
result_set = db.query("sql", "SELECT * FROM Product WHERE price > 100")
for result in result_set:
json_str = result.to_json()
print(json_str)
# {"@rid":"#1:0","@type":"Product","name":"Laptop","price":999.99}
Note: The JSON includes ArcadeDB metadata like @rid (record ID) and @type (type name).
Note: Array/list properties are serialized as JSON arrays in to_json().
Common Patterns¶
Converting to Lists and Dicts¶
ResultSet.to_list() and Result.to_dict() are eager materializers. They are the
right choice when you explicitly want Python-native data, but they are not the
lowest-overhead path for large result sets.
# List of dictionaries (most common)
result_set = db.query("sql", "SELECT FROM User")
users = [result.to_dict() for result in result_set]
# List of specific property values
result_set = db.query("sql", "SELECT name FROM User")
names = [result.get("name") for result in result_set]
# Dictionary keyed by ID
result_set = db.query("sql", "SELECT id, name FROM User")
user_map = {
result.get("id"): result.get("name")
for result in result_set
}
Pandas Integration¶
import pandas as pd
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./mydb")
# Query and convert to DataFrame
result_set = db.query("sql", "SELECT name, age, city FROM Person")
df = pd.DataFrame([result.to_dict() for result in result_set])
print(df.head())
# name age city
# 0 Alice 30 NYC
# 1 Bob 25 LA
# 2 Charlie 35 Boston
Processing Large Result Sets¶
For memory efficiency with large datasets:
# Stream one row at a time when you only need a few fields
result_set = db.query("sql", "SELECT name, email FROM LargeTable")
for result in result_set:
process_row(result.get("name"), result.get("email"))
# Or process in batches when you do need dict materialization
result_set = db.query("sql", "SELECT FROM LargeTable")
batch = []
batch_size = 1000
for result in result_set:
batch.append(result.to_dict())
if len(batch) >= batch_size:
# Process batch
process_batch(batch)
batch = []
# Process remaining
if batch:
process_batch(batch)
Conditional Property Access¶
result_set = db.query("sql", "SELECT * FROM Product")
for result in result_set:
# Safely get optional properties
discount = (
result.get("discount")
if result.has_property("discount")
else 0.0
)
price = result.get("price")
final_price = price * (1 - discount)
print(f"Price: ${final_price:.2f}")
Extracting RIDs and Types¶
result_set = db.query("sql", "SELECT FROM Person")
for result in result_set:
# Get ArcadeDB metadata
rid = result.get("@rid") # Record ID (e.g., "#1:0")
rec_type = result.get("@type") # Type name (e.g., "Person")
# Get user properties
name = result.get("name")
print(f"[{rid}] {rec_type}: {name}")
Converting Results to Vertices for Modification¶
Query results are read-only by default. To modify a vertex or edge returned from a query, convert it to a mutable Vertex or Edge object using .get_vertex() or .get_edge().
get_vertex() -> Optional[Vertex]¶
Convert a Result to a mutable Vertex object (if the result is a vertex).
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./mydb")
# Query returns read-only Results
result_set = db.query("sql", "SELECT FROM Person WHERE name = 'Alice'")
with db.transaction():
for result in result_set:
# Convert Result to mutable Vertex
vertex = result.get_vertex()
if vertex:
# Now you can modify it
vertex.set("age", 31)
vertex.set("updated", True)
vertex.save()
print(f"Updated: {result.get('name')}")
get_edge() -> Optional[Edge]¶
Convert a Result to a mutable Edge object (if the result is an edge).
# Query edges
result_set = db.query("sql", "SELECT FROM FRIEND_OF")
with db.transaction():
for result in result_set:
# Convert Result to mutable Edge
edge = result.get_edge()
if edge:
edge.set("strength", 0.95)
edge.save()
Full Example: Bulk Update with Caching¶
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./mydb")
# Query all movies
movies = list(db.query("sql", "SELECT FROM Movie"))
print(f"Processing {len(movies)} movies...")
with db.transaction():
for movie_result in movies:
# Convert to mutable vertex
movie = movie_result.get_vertex()
if not movie:
continue
# Modify the vertex
title = movie_result.get("title")
# Add embedding or update properties
movie.set("processed", True)
movie.set("updated_at", "2024-01-02")
movie.save()
print(f"✓ Updated: {title}")
db.close()
Key Distinction:
| Object | Read | Write |
|---|---|---|
Result (from query) |
✅ Yes | ❌ No |
Vertex/Edge (mutable) |
✅ Yes | ✅ Yes |
Created with db.new_vertex() |
✅ Yes | ✅ Yes |
Looked up with db.lookup_by_rid() |
✅ Yes | ✅ Yes |
Complete Examples¶
User Search and Display¶
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./users_db")
def search_users(name_pattern):
"""Search users by name pattern."""
query = f"""
SELECT name, email, created_at
FROM User
WHERE name LIKE '%{name_pattern}%'
ORDER BY name
"""
result_set = db.query("sql", query)
users = []
for result in result_set:
user = {
'name': result.get("name"),
'email': result.get("email"),
'created_at': result.get("created_at")
}
users.append(user)
return users
# Search
results = search_users("John")
print(f"Found {len(results)} users:")
for user in results:
print(f" {user['name']} <{user['email']}>")
db.close()
Graph Traversal Results¶
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./social_graph")
# Find friends of friends
query = """
SELECT
@rid as person_rid,
name,
out('Follows').out('Follows').name as friends_of_friends
FROM Person
WHERE name = 'Alice'
"""
result_set = db.query("sql", query)
for result in result_set:
person_name = result.get("name")
friends_of_friends = result.get("friends_of_friends")
print(f"{person_name}'s extended network:")
# friends_of_friends is a Java collection, convert to Python
if friends_of_friends:
fof_list = list(friends_of_friends)
for friend in fof_list:
print(f" - {friend}")
db.close()
Aggregation Results¶
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./analytics_db")
# Group by and aggregation
query = """
SELECT
category,
COUNT(*) as product_count,
AVG(price) as avg_price,
MAX(price) as max_price
FROM Product
GROUP BY category
ORDER BY product_count DESC
"""
result_set = db.query("sql", query)
print("Product Statistics by Category:")
print("-" * 60)
for result in result_set:
category = result.get("category")
count = result.get("product_count")
avg_price = result.get("avg_price")
max_price = result.get("max_price")
print(f"{category}:")
print(f" Products: {count}")
print(f" Avg Price: ${avg_price:.2f}")
print(f" Max Price: ${max_price:.2f}")
print()
db.close()
Export to JSON File¶
import arcadedb_embedded as arcadedb
import json
db = arcadedb.open_database("./mydb")
# Export query results to JSON file
result_set = db.query("sql", "SELECT * FROM Document")
# Method 1: Using to_dict()
documents = [result.to_dict() for result in result_set]
with open("export.json", "w") as f:
json.dump(documents, f, indent=2, default=str)
# Method 2: Using to_json() directly
result_set = db.query("sql", "SELECT * FROM Document")
with open("export_raw.jsonl", "w") as f:
for result in result_set:
f.write(result.to_json() + "\n")
db.close()
Cypher Query Results¶
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./graph_db")
# OpenCypher queries also return ResultSet
cypher_query = """
MATCH (p:Person)-[:WORKS_AT]->(c:Company)
WHERE c.name = 'TechCorp'
RETURN p.name AS employee, p.role AS position
"""
result_set = db.query("opencypher", cypher_query)
print("TechCorp Employees:")
for result in result_set:
employee = result.get("employee")
position = result.get("position")
print(f" {employee} - {position}")
db.close()
Error Handling¶
from arcadedb_embedded import ArcadeDBError
result_set = db.query("sql", "SELECT * FROM Person")
for result in result_set:
try:
# Safe property access
name = result.get("name")
# May not exist
if result.has_property("phone"):
phone = result.get("phone")
else:
phone = "N/A"
print(f"{name}: {phone}")
except ArcadeDBError as e:
print(f"Error accessing properties: {e}")
continue
Type Handling¶
ArcadeDB returns Java types that are automatically converted:
| Java Type | Python Type | Notes |
|---|---|---|
java.lang.String |
str |
Direct conversion |
java.lang.Integer, Long |
int |
Numeric conversion |
java.lang.Float, Double |
float |
Numeric conversion |
java.lang.Boolean |
bool |
Explicitly converted |
java.util.ArrayList |
list |
Iterable conversion |
java.util.HashMap |
dict |
Key-value conversion |
null |
None |
Direct mapping |
Boolean Conversion:
The Result class explicitly converts Java Boolean to Python bool:
# This is handled automatically
result_set = db.query("sql", "SELECT active FROM User")
for result in result_set:
active = result.get("active") # Python bool
if active: # Works as expected
print("User is active")
Performance Tips¶
Minimize Property Access¶
# Less efficient: Multiple property accesses
for result in result_set:
if result.get("age") > 25:
name = result.get("name")
age = result.get("age")
print(f"{name}: {age}")
# More efficient: Access once, reuse
for result in result_set:
age = result.get("age")
if age > 25:
name = result.get("name")
print(f"{name}: {age}")
Use to_dict() for Multiple Properties¶
# When accessing many properties, convert to dict once
for result in result_set:
data = result.to_dict()
# Now access from Python dict (faster)
process(
data["name"],
data["age"],
data["email"],
data["phone"]
)
Stream Processing¶
# Don't collect all results if you can process incrementally
result_set = db.query("sql", "SELECT * FROM LargeTable")
# Process as you iterate (memory efficient)
total = 0
for result in result_set:
value = result.get("amount")
total += value
# Better than:
# results = list(result_set) # Loads everything into memory
See Also¶
- Database API - Query and command methods
- Query Guide - Writing effective queries
- Transaction API - Transaction context
- Graph Operations Guide - Working with graph results