Skip to main content

5-Minute Quickstart

Get up and running with dqlitepy in 5 minutes! This guide shows you how to create a single-node database and a 3-node cluster.

Prerequisites

  • Python 3.8 or later
  • dqlitepy installed (pip install dqlitepy-*.whl)

Single Node - 2 Minutes

Create a simple dqlite database in just a few lines:

from dqlitepy import Node

# Create and start a node
node = Node(address="127.0.0.1:9001", data_dir="/tmp/dqlite-data")
node.start()

# Open a database
node.open_db("myapp.db")

# Create a table and insert data
node.exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)")
node.exec("INSERT INTO users (name, email) VALUES (?, ?)", ["Alice", "alice@example.com"])
node.exec("INSERT INTO users (name, email) VALUES (?, ?)", ["Bob", "bob@example.com"])

# Query data
results = node.query("SELECT * FROM users")
for row in results["rows"]:
print(f"User {row[0]}: {row[1]} ({row[2]})")

# Clean up
node.close()

Output:

User 1: Alice (alice@example.com)
User 2: Bob (bob@example.com)

3-Node Cluster - 3 Minutes

Create a fault-tolerant cluster with automatic replication:

from dqlitepy import Node
import time

# Define cluster topology
cluster_addresses = [
"127.0.0.1:9001",
"127.0.0.1:9002",
"127.0.0.1:9003"
]

# Create and start all nodes
nodes = []
for i, address in enumerate(cluster_addresses, 1):
node = Node(
address=address,
data_dir=f"/tmp/node{i}",
node_id=i,
cluster=cluster_addresses
)
node.start()
nodes.append(node)
time.sleep(0.5) # Brief delay for cluster formation

# Use the first node (leader will be elected automatically)
leader = nodes[0]
leader.open_db("cluster.db")

# Create table and insert data
leader.exec("""
CREATE TABLE messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)
""")
leader.exec("INSERT INTO messages (content) VALUES (?)", ["Hello from the cluster!"])

# Query from ANY node - data is automatically replicated
for i, node in enumerate(nodes, 1):
print(f"\n--- Reading from Node {i} ---")
results = node.query("SELECT * FROM messages")
for row in results["rows"]:
print(f"Message {row[0]}: {row[1]} at {row[2]}")

# Clean up
for node in nodes:
node.close()

Output:

--- Reading from Node 1 ---
Message 1: Hello from the cluster! at 2025-10-17 16:30:45

--- Reading from Node 2 ---
Message 1: Hello from the cluster! at 2025-10-17 16:30:45

--- Reading from Node 3 ---
Message 1: Hello from the cluster! at 2025-10-17 16:30:45

Using SQLAlchemy ORM

Prefer using an ORM? Here's a complete example:

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from dqlitepy import Node
from dqlitepy.sqlalchemy import register_dqlite_node

# Start a node
node = Node("127.0.0.1:9001", "/tmp/dqlite-orm")
node.start()
node.open_db("app.db")

# Register with SQLAlchemy
register_dqlite_node(node, "app.db")

# Create ORM models
Base = declarative_base()

class User(Base):
__tablename__ = 'users'

id = Column(Integer, primary_key=True)
name = Column(String(100))
email = Column(String(100))

# Create engine and session
engine = create_engine('dqlite:///app.db')
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

# Use the ORM
alice = User(name='Alice', email='alice@example.com')
bob = User(name='Bob', email='bob@example.com')

session.add_all([alice, bob])
session.commit()

# Query using ORM
users = session.query(User).all()
for user in users:
print(f"{user.name}: {user.email}")

# Clean up
session.close()
node.close()

Next Steps

Now that you've got the basics down, here are some recommended next steps:

Tips

  • Use specific IPs: Always use actual IP addresses (like 127.0.0.1), never 0.0.0.0
  • Wait for cluster formation: Add small delays when starting multiple nodes
  • Check the leader: Use client.leader() to find which node is the current leader
  • Handle errors: Wrap operations in try/except to handle NoLeaderError during elections
  • Data directory: Each node needs its own unique data directory

Common Issues

Port Already in Use

# Error: Address already in use
# Solution: Use different ports or stop existing processes
node1 = Node("127.0.0.1:9001", "/tmp/node1") # OK
node2 = Node("127.0.0.1:9002", "/tmp/node2") # Different port - OK

No Leader Error

# Error: NoLeaderError during cluster startup
# Solution: Wait for leader election
import time
from dqlitepy.exceptions import NoLeaderError

for attempt in range(5):
try:
node.query("SELECT 1")
break
except NoLeaderError:
time.sleep(1)

Permission Denied

# Error: Permission denied on data directory
# Solution: Ensure directory exists and is writable
import os
os.makedirs("/tmp/mydata", exist_ok=True)
node = Node("127.0.0.1:9001", "/tmp/mydata")

Ready to build something? Check out our FastAPI Example to see a complete application!