Simple Document Store Example¶
This comprehensive example demonstrates ArcadeDB's document capabilities using a task management system. You'll learn about data types, NULL handling, SQL operations, and the differences between document and graph storage models.
Overview¶
The example creates a task management system showcasing:
- Rich Data Types - STRING, BOOLEAN, INTEGER, FLOAT, DECIMAL, DATE, DATETIME, LIST with element types, and Arrays
- NULL Handling - INSERT with NULL, UPDATE to NULL, queries with IS NULL/IS NOT NULL
- SQL Operations - Complete CRUD workflow with ArcadeDB SQL
- Built-in Functions - date() for date literals, uuid() for unique IDs, sysdate() for dynamic timestamps
- Record Types - Understanding Documents vs Vertices vs Edges
- Schema Flexibility - Typed properties for performance with schema-optional flexibility
- Type Safety - Validated array data with element type specification
Key Learning Points¶
1. Data Type Support¶
ArcadeDB provides comprehensive data type support with NULL handling:
from datetime import date
import uuid
import arcadedb_embedded as arcadedb
with arcadedb.create_database("./task_db") as db:
# Schema operations are auto-transactional (no wrapper needed)
db.schema.create_document_type("Task")
db.schema.create_property("Task", "title", "STRING")
db.schema.create_property("Task", "priority", "STRING")
db.schema.create_property("Task", "completed", "BOOLEAN")
db.schema.create_property("Task", "tags", "LIST", of_type="STRING")
db.schema.create_property("Task", "created_date", "DATE")
db.schema.create_property("Task", "due_datetime", "DATETIME")
db.schema.create_property("Task", "estimated_hours", "FLOAT")
db.schema.create_property("Task", "priority_score", "INTEGER")
db.schema.create_property("Task", "cost", "DECIMAL")
db.schema.create_property("Task", "task_id", "STRING")
# Insert with Python objects (auto-converted) and UUID
with db.transaction():
task = db.new_document("Task")
task.set("title", "Write documentation")
task.set("priority", "medium")
task.set("completed", False)
task.set("tags", ["work", "writing"])
task.set("created_date", date(2024, 1, 16))
task.set("due_datetime", None)
task.set("estimated_hours", 8.0)
task.set("priority_score", 70)
task.set("cost", None)
task.set("task_id", str(uuid.uuid4()))
task.save()
2. SQL Functions and NULL Queries¶
Learn about built-in functions and NULL handling:
from datetime import datetime
import uuid
import arcadedb_embedded as arcadedb
with arcadedb.open_database("./task_db") as db:
# Insert with Python-native types (UUID, datetime handled by converter)
with db.transaction():
task = db.new_document("Task")
task.set("title", "Buy groceries")
task.set("task_id", str(uuid.uuid4()))
task.set("created_date", date(2024, 1, 15))
task.set("due_datetime", datetime(2024, 1, 20, 18, 0, 0))
task.set("cost", 150.00)
task.save()
# Query for NULL values (reads don't need transaction)
print("Tasks with NULL due_datetime:")
result = db.query("sql", "SELECT title, due_datetime, cost FROM Task WHERE due_datetime IS NULL")
for record in result:
print(f" Title: {record.get('title')}, Due: {record.get('due_datetime')}, Cost: {record.get('cost')}")
print("\nTasks with NULL cost:")
result = db.query("sql", "SELECT title, due_datetime, cost FROM Task WHERE cost IS NULL")
for record in result:
print(f" Title: {record.get('title')}, Due: {record.get('due_datetime')}, Cost: {record.get('cost')}")
# UPDATE via API (fetch + mutate in transaction)
with db.transaction():
for record in db.query("sql", "SELECT FROM Task WHERE title = 'Call dentist'"):
doc = record.get_element()
doc.set("cost", None)
doc.set("estimated_hours", None)
doc.save()
3. Record Types Explained¶
Understanding when to use different record types:
- Document - Like database tables, for simple data storage
- Vertex - Graph nodes representing entities
- Edge - Graph connections representing relationships
4. Advanced Features¶
The example demonstrates:
- NULL Values - Optional fields with IS NULL/IS NOT NULL queries
- Type-Safe Arrays - LIST with of_type parameter for validated collections
- DECIMAL Handling - Java BigDecimal conversion via float(str(value))
- DATETIME Literals - String literals automatically parsed to DATETIME type
- Schema-Optional Flexibility - Define properties for performance, add ad-hoc fields when needed
- Query Optimization - Using typed properties and indexes
Running the Example¶
Expected output includes:
- Database creation and schema setup
- Sample tasks with various data types and NULL values
- Query demonstrations including NULL checks
- UPDATE operations setting values to NULL
- File structure explanation
Database Structure¶
After running, examine the created files:
my_test_databases/task_db/
├── configuration.json # Database configuration
├── schema.json # Type definitions with LIST OF STRING
├── Task_*.bucket # Data storage files with tasks
├── dictionary.*.dict # String compression dictionary
└── statistics.json # Database statistics
Next Steps¶
After mastering this example:
- Explore Graph Operations - Learn about vertices and edges
- Try Vector Search - Modern AI/ML integration
- Review API Documentation - Deep dive into advanced features
Common Questions¶
Q: How does ArcadeDB handle NULL values? A: All ArcadeDB types support NULL by default. You can INSERT NULL, UPDATE to NULL, and query with IS NULL/IS NOT NULL operators.
Q: How do I create a LIST with STRING elements?
A: In Python API: db.schema.create_property("Task", "tags", "LIST", of_type="STRING").
In SQL: CREATE PROPERTY Task.tags LIST OF STRING. Both create a type-safe list of
strings.
Q: Why use typed properties? A: They provide better performance, validation, and enable advanced features like indexes. But ArcadeDB is schema-optional - you can still add properties dynamically.
Q: When should I use Documents vs Vertices? A: Use Documents for simple data storage (like SQL tables). Use Vertices when you need to model relationships between entities with Edges.
Q: How do I handle Java BigDecimal in Python?
A: Convert via string first: float(str(decimal_value)). Direct conversion from Java BigDecimal to Python float requires string intermediary.
Q: Can I mix data types? A: Yes! ArcadeDB is schema-flexible. You can add properties dynamically while benefiting from typed properties where defined.