Skip to main content

Simple Node Example

A minimal example demonstrating how to create and use a single dqlite node with basic CRUD operations.

Overview

This example shows the fundamentals of working with dqlitepy:

  • Initializing a dqlite node
  • Creating tables
  • Inserting data
  • Querying results
  • Proper resource cleanup

Perfect for: First-time users learning the basics of dqlitepy.

Prerequisites

  • Python 3.12 or higher
  • uv package manager installed
  • dqlitepy installed in your project

Quick Start

The fastest way to run this example:

cd examples/simple_node
./quickstart.sh

The script will:

  1. Install dqlitepy from the repository
  2. Run the example
  3. Display the output

Manual Installation

If you prefer to run it manually:

cd examples/simple_node
uv sync
uv run python -m simple_node_example.main

Code Walkthrough

Initialization

from dqlitepy import Node
import os
import tempfile

# Create a temporary directory for the node
data_dir = tempfile.mkdtemp(prefix="dqlite_simple_")

# Initialize the node
node = Node(
node_id=1,
address="127.0.0.1:9001",
data_dir=data_dir
)

Key Points:

  • Each node needs a unique ID and address
  • The data directory stores the Raft log and snapshots
  • Using a temporary directory for this example

Database Operations

# Set up the node as a standalone cluster
node.set_bind_address("127.0.0.1:9001")
node.set_cluster([{"id": 1, "address": "127.0.0.1:9001"}])

# Open a connection
conn = node.open("example.db")
cursor = conn.cursor()

# Create a table
cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
)
""")

Key Points:

  • set_bind_address() - Sets the node's listening address
  • set_cluster() - Defines the initial cluster configuration
  • node.open() - Opens a database connection
  • Standard SQL operations work as expected

Inserting Data

# Insert some sample data
users = [
(1, "Alice", "alice@example.com"),
(2, "Bob", "bob@example.com"),
(3, "Charlie", "charlie@example.com")
]

cursor.executemany(
"INSERT INTO users (id, name, email) VALUES (?, ?, ?)",
users
)
conn.commit()

Key Points:

  • Use parameterized queries to prevent SQL injection
  • executemany() for batch inserts
  • Always commit transactions

Querying Data

# Query the data
cursor.execute("SELECT id, name, email FROM users ORDER BY id")
results = cursor.fetchall()

print("\nUsers in database:")
for user_id, name, email in results:
print(f" {user_id}: {name} ({email})")

Key Points:

  • Standard DB-API 2.0 cursor operations
  • fetchall() retrieves all results
  • Results are returned as tuples

Cleanup

# Clean up
cursor.close()
conn.close()
node.close()

# Remove temporary directory
import shutil
shutil.rmtree(data_dir)

Key Points:

  • Always close cursors, connections, and nodes
  • Clean up temporary directories
  • Proper resource management prevents leaks

Expected Output

When you run the example, you should see:

Initializing single dqlite node...
Creating database and table...
Inserting sample data...

Users in database:
1: Alice (alice@example.com)
2: Bob (bob@example.com)
3: Charlie (charlie@example.com)

Example completed successfully!

Common Issues

Port Already in Use

If you see an error about the port being in use:

node = Node(
node_id=1,
address="127.0.0.1:9002", # Try a different port
data_dir=data_dir
)

Permission Errors

Make sure the data directory is writable:

chmod 755 /path/to/data/dir

Source Code

The complete source code is available at:

Next Steps

After mastering this example, try:

  1. Multi-Node Cluster - Learn about clustering
  2. Cluster with Client - Use the client API
  3. SQLAlchemy ORM - Use an ORM with dqlitepy