Skip to main content

SQLite extension for graph queries using Cypher

Project description

GraphQLite Python

Python bindings for GraphQLite, a SQLite extension that adds graph database capabilities using Cypher.

Installation

pip install graphqlite

Quick Start

High-Level Graph API (Recommended)

The Graph class provides an ergonomic interface for common graph operations:

from graphqlite import Graph

# Create a graph (in-memory or file-based)
g = Graph(":memory:")

# Add nodes
g.upsert_node("alice", {"name": "Alice", "age": 30}, label="Person")
g.upsert_node("bob", {"name": "Bob", "age": 25}, label="Person")

# Add edges
g.upsert_edge("alice", "bob", {"since": 2020}, rel_type="KNOWS")

# Query
print(g.stats())              # {'nodes': 2, 'edges': 1}
print(g.get_neighbors("alice"))  # [{'id': 'bob', ...}]
print(g.node_degree("alice"))    # 1

# Graph algorithms
ranks = g.pagerank()
communities = g.community_detection()

# Raw Cypher when needed
results = g.query("MATCH (a)-[:KNOWS]->(b) RETURN a.name, b.name")

Low-Level Cypher API

For complex queries or when you need full control:

from graphqlite import connect

db = connect("graph.db")

db.cypher("CREATE (a:Person {name: 'Alice', age: 30})")
db.cypher("CREATE (b:Person {name: 'Bob', age: 25})")
db.cypher("""
    MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})
    CREATE (a)-[:KNOWS]->(b)
""")

results = db.cypher("MATCH (a:Person)-[:KNOWS]->(b) RETURN a.name, b.name")
for row in results:
    print(f"{row['a.name']} knows {row['b.name']}")

API Reference

Graph Class

from graphqlite import Graph, graph

# Constructor
g = Graph(db_path=":memory:", namespace="default", extension_path=None)

# Or use the factory function
g = graph(":memory:")

Node Operations

Method Description
upsert_node(node_id, props, label="Entity") Create or update a node
get_node(node_id) Get node by ID
has_node(node_id) Check if node exists
delete_node(node_id) Delete node and its edges
get_all_nodes(label=None) Get all nodes, optionally by label

Edge Operations

Method Description
upsert_edge(source, target, props, rel_type="RELATED") Create edge between nodes
get_edge(source, target) Get edge properties
has_edge(source, target) Check if edge exists
delete_edge(source, target) Delete edge
get_all_edges() Get all edges

Graph Queries

Method Description
node_degree(node_id) Count edges connected to node
get_neighbors(node_id) Get adjacent nodes
get_node_edges(node_id) Get all edges for a node
stats() Get node/edge counts
query(cypher) Execute raw Cypher query

Graph Algorithms

Centrality

Method Description
pagerank(damping=0.85, iterations=20) PageRank importance scores
degree_centrality() In/out/total degree for each node
betweenness_centrality() Betweenness centrality scores
closeness_centrality() Closeness centrality scores
eigenvector_centrality(iterations=100) Eigenvector centrality scores

Community Detection

Method Description
community_detection(iterations=10) Label propagation communities
louvain(resolution=1.0) Louvain modularity optimization
leiden_communities(resolution, seed) Leiden algorithm (requires graspologic)

Connected Components

Method Description
weakly_connected_components() Weakly connected components
strongly_connected_components() Strongly connected components

Path Finding

Method Description
shortest_path(source, target, weight) Dijkstra's shortest path
astar(source, target, lat, lon) A* with optional heuristic
all_pairs_shortest_path() All-pairs shortest paths (Floyd-Warshall)

Traversal

Method Description
bfs(start, max_depth=-1) Breadth-first search
dfs(start, max_depth=-1) Depth-first search

Similarity

Method Description
node_similarity(n1, n2, threshold, top_k) Jaccard similarity
knn(node, k=10) K-nearest neighbors
triangle_count() Triangle counts and clustering coefficients

Export

Method Description
to_rustworkx() Export to rustworkx PyDiGraph (requires rustworkx)

Batch Operations

# Batch insert nodes (upsert semantics)
g.upsert_nodes_batch([
    ("n1", {"name": "Alice"}, "Person"),
    ("n2", {"name": "Bob"}, "Person"),
])

# Batch insert edges (upsert semantics)
g.upsert_edges_batch([
    ("n1", "n2", {"weight": 1.0}, "KNOWS"),
])

Bulk Insert (High Performance)

For maximum throughput when building graphs from external data, use the bulk insert methods. These bypass Cypher parsing entirely and use direct SQL, achieving 100-500x faster insert rates.

# Bulk insert nodes - returns dict mapping external_id -> internal_rowid
id_map = g.insert_nodes_bulk([
    ("alice", {"name": "Alice", "age": 30}, "Person"),
    ("bob", {"name": "Bob", "age": 25}, "Person"),
    ("charlie", {"name": "Charlie"}, "Person"),
])

# Bulk insert edges using the ID map - no MATCH queries needed!
edges_inserted = g.insert_edges_bulk([
    ("alice", "bob", {"since": 2020}, "KNOWS"),
    ("bob", "charlie", {"since": 2021}, "KNOWS"),
], id_map)

# Or use the convenience method for both
result = g.insert_graph_bulk(nodes=nodes, edges=edges)
print(f"Inserted {result.nodes_inserted} nodes, {result.edges_inserted} edges")

# Resolve existing node IDs (for edges to pre-existing nodes)
resolved = g.resolve_node_ids(["alice", "bob"])
Method Description
insert_nodes_bulk(nodes) Insert nodes, returns ID mapping dict
insert_edges_bulk(edges, id_map=None) Insert edges using ID map
insert_graph_bulk(nodes, edges) Insert both, returns BulkInsertResult
resolve_node_ids(ids) Resolve external IDs to internal rowids

Connection Class

from graphqlite import connect, wrap

# Open new connection
db = connect("graph.db")
db = connect(":memory:")

# Wrap existing sqlite3 connection
import sqlite3
conn = sqlite3.connect("graph.db")
db = wrap(conn)

Methods

Method Description
cypher(query) Execute Cypher query, return results
execute(sql) Execute raw SQL
close() Close connection

CypherResult

Results from cypher() calls:

results = db.cypher("MATCH (n) RETURN n.name")

len(results)           # Number of rows
results[0]             # First row as dict
results.columns        # Column names
results.to_list()      # All rows as list

for row in results:
    print(row["n.name"])

Utility Functions

from graphqlite import escape_string, sanitize_rel_type, CYPHER_RESERVED

# Escape strings for Cypher queries
safe = escape_string("It's a test")  # "It\\'s a test"

# Sanitize relationship types
rel = sanitize_rel_type("has-items")  # "has_items"
rel = sanitize_rel_type("CREATE")     # "REL_CREATE" (reserved word)

# Set of Cypher reserved keywords
if "MATCH" in CYPHER_RESERVED:
    print("MATCH is reserved")

Extension Path

The extension is located automatically. To specify a custom path:

db = connect("graph.db", extension_path="/path/to/graphqlite.dylib")

Or set the GRAPHQLITE_EXTENSION_PATH environment variable.

Troubleshooting

See FAQ.md for common issues and solutions.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

graphqlite-0.5.0.tar.gz (461.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

graphqlite-0.5.0-py3-none-win_amd64.whl (1.4 MB view details)

Uploaded Python 3Windows x86-64

graphqlite-0.5.0-py3-none-manylinux_2_28_aarch64.whl (329.2 kB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

graphqlite-0.5.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (331.9 kB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

graphqlite-0.5.0-py3-none-macosx_11_0_arm64.whl (259.0 kB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file graphqlite-0.5.0.tar.gz.

File metadata

  • Download URL: graphqlite-0.5.0.tar.gz
  • Upload date:
  • Size: 461.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for graphqlite-0.5.0.tar.gz
Algorithm Hash digest
SHA256 61f6f8c84cb191a278cc4ac2900bf7b7ecaeefa6f2334bd7933342df5fd7b9e0
MD5 7dff936655c0c996c9e79c76f7995df5
BLAKE2b-256 08d6a43a3d0d5456cfeef60493f0d75d5e9d33a2b13cf4e25f0bfaee7f2c88fa

See more details on using hashes here.

File details

Details for the file graphqlite-0.5.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: graphqlite-0.5.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for graphqlite-0.5.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 0f96ad8048fe42746d891de42ae8ad1ef8e55f61091cf88aeb14172ded47a187
MD5 c5bceffcf0d56f0b72d99942fae6f52c
BLAKE2b-256 8bdf480bbdca11b0a3e13bc202b66bd10767c22582f9be3ae0d789dd37f7629d

See more details on using hashes here.

File details

Details for the file graphqlite-0.5.0-py3-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for graphqlite-0.5.0-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 91a6edab656705bd9e9ea3e635f674dd4b7c29436e5e9677c7031eca4e17ed6d
MD5 4cb864fba95412fb8013b7769a97f378
BLAKE2b-256 29d94fc46d42853efb1b1d71f3529ef40793b3cd631466d54bab1efaeea9c15e

See more details on using hashes here.

File details

Details for the file graphqlite-0.5.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for graphqlite-0.5.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 8001ccba5d00ce8e5bf5991f0a33a0aea49c8a0bf8e2b607a907fa9080b8c768
MD5 3aa59dc79b51dbaf6db5ffdcbe012432
BLAKE2b-256 4dce0adb8633c38e4155c0f655d1648481f8c06d9afa64118b142c00bb0562b5

See more details on using hashes here.

File details

Details for the file graphqlite-0.5.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for graphqlite-0.5.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 43bb4512d2dde1420304511b6ea64db2874633293d74b4a32004c31b492925fe
MD5 ed4924c00832de411f5636cd1b20a9a6
BLAKE2b-256 90b36d3463fc82dfaf5e2a17b2a5f5bcb2460cc7a863088ccb72eef9f53b9d3a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page