Skip to main content

GestaltDB

Coverage Documentation

GestaltDB is a pure Python graph database toolkit for attributed graphs. It stores nodes, edges, labels, typed adjacency records, and property indexes on embedded key-value backends.

Documentation: https://mylonasc.github.io/gestaltdb/

Install From PyPI

With pip:

python -m pip install gestaltdb

With uv:

uv add gestaltdb

Install columnar ingestion dependencies:

python -m pip install "gestaltdb[arrow,polars]"

Install all optional backends and serializers:

python -m pip install "gestaltdb[all]"

Optional extras include lmdb, leveldb, rocksdb, arrow, polars, fast-ingest, msgpack, protobuf, bloom, docs, dev, and all.

Basic Example

from tempfile import TemporaryDirectory

from gestaltdb.graphdb import Edge, GraphDB, Node
from gestaltdb.kvstores import LevelDBStore
from gestaltdb.serializers import PickleSerializer

with TemporaryDirectory() as tmpdir:
    graph = GraphDB(LevelDBStore(path=f"{tmpdir}/graph"), PickleSerializer())

    graph.put_node(Node(node_id="alice", labels=["Person"], properties={"name": "Alice"}))
    graph.put_node(Node(node_id="bob", labels=["Person"], properties={"name": "Bob"}))
    graph.put_edge(Edge(
        edge_id="alice-knows-bob",
        source="alice",
        target="bob",
        properties={"type": "knows", "since": 2024},
    ))

    result = graph.query('MATCH (a:Person {name: "Alice"}) MATCH (a)-[:knows]->(b) RETURN a.id, b.name')
    print(result.records)

    graph.close()

Arrow Ingestion Example

This example ingests entity columns from PyArrow arrays. JSONSerializer lets GestaltDB build node and edge payloads from structured columns.

from tempfile import TemporaryDirectory

import pyarrow as pa

from gestaltdb.graphdb import GraphDB
from gestaltdb.kvstores import LevelDBStore
from gestaltdb.serializers import JSONSerializer

with TemporaryDirectory() as tmpdir:
    graph = GraphDB(LevelDBStore(path=f"{tmpdir}/graph"), JSONSerializer())

    graph.ingest_nodes_arrow_entities(
        pa.array(["alice", "bob", "carol"]),
        labels=pa.array([["Person"], ["Person"], ["Person"]]),
        properties={
            "name": pa.array(["Alice", "Bob", "Carol"]),
            "age": pa.array([34, 36, 29]),
        },
    )

    graph.ingest_edges_arrow_entities(
        pa.array(["alice-knows-bob", "bob-knows-carol"]),
        pa.array(["alice", "bob"]),
        pa.array(["bob", "carol"]),
        pa.array(["knows", "knows"]),
        properties={"since": pa.array([2024, 2025])},
    )

    result = graph.query('MATCH (a:Person {name: "Alice"}) MATCH (a)-[:knows]->(b) RETURN a.id, b.name')
    print(result.records)

    graph.close()

Polars Ingestion Example

This example ingests the same graph from Polars DataFrames. Property columns are converted into node and edge payloads during ingestion.

from tempfile import TemporaryDirectory

import polars as pl

from gestaltdb.graphdb import GraphDB
from gestaltdb.kvstores import LevelDBStore
from gestaltdb.serializers import JSONSerializer

nodes = pl.DataFrame({
    "node_id": ["alice", "bob", "carol"],
    "labels": [["Person"], ["Person"], ["Person"]],
    "name": ["Alice", "Bob", "Carol"],
    "age": [34, 36, 29],
})

edges = pl.DataFrame({
    "edge_id": ["alice-knows-bob", "bob-knows-carol"],
    "source": ["alice", "bob"],
    "target": ["bob", "carol"],
    "edge_type": ["knows", "knows"],
    "since": [2024, 2025],
})

with TemporaryDirectory() as tmpdir:
    graph = GraphDB(LevelDBStore(path=f"{tmpdir}/graph"), JSONSerializer())

    graph.ingest_nodes_polars_entities(nodes)
    graph.ingest_edges_polars_entities(edges)

    result = graph.query('MATCH (a:Person) MATCH (a)-[:knows]->(b) RETURN a.name, b.name ORDER BY a.name')
    print(result.records)

    graph.close()

Install From A Checkout

From a local checkout:

uv sync

Install into another project:

uv add /path/to/gestaltdb

With pip:

python -m pip install /path/to/gestaltdb

Features

  • Attributed Node and Edge objects with stable IDs.
  • Native node labels and typed edge traversal through edge.properties["type"].
  • LMDB, LevelDB, and RocksDB/PyRex storage backends.
  • Pickle, JSON, MessagePack, and Protobuf serializers.
  • Label, relationship type, property, composite, and range indexes.
  • Read-only Cypher subset for indexed scans, typed traversal, filtering, ordering, limits, and chained MATCH clauses.
  • Bulk and columnar ingestion helpers for Arrow and Polars.
  • Typed path and subgraph sampling.

See the full documentation for backend selection, indexing, Cypher syntax, ingestion, sampling, and benchmarks.

Name origin

The name GestaltDB is inspired by Gestalt psychology and the idea that the whole is something more than its parts.

Download files

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

Source Distribution

gestaltdb-0.3.0.tar.gz (60.8 kB view details)

Uploaded Source

Built Distribution

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

gestaltdb-0.3.0-py3-none-any.whl (48.5 kB view details)

Uploaded Python 3

File details

Details for the file gestaltdb-0.3.0.tar.gz.

File metadata

  • Download URL: gestaltdb-0.3.0.tar.gz
  • Upload date:
  • Size: 60.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gestaltdb-0.3.0.tar.gz
Algorithm Hash digest
SHA256 dd58889c67f084d453a33aee193a3f81cd590ec4acc28ec038cfff93c5ba202b
MD5 834b22ad1859d1f999a48448f8778515
BLAKE2b-256 f3820749cd28530959fd80a5708ad01d69d690dedda45c83fddd431068937e57

See more details on using hashes here.

Provenance

The following attestation bundles were made for gestaltdb-0.3.0.tar.gz:

Publisher: publish.yml on mylonasc/gestaltdb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gestaltdb-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: gestaltdb-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 48.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gestaltdb-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bc1ed9168e2562efdf8b6889e0c542079fb72df26f469822cfa00955f983e446
MD5 696ea63387ee0dc0861f503034725946
BLAKE2b-256 5ea898ad368e1e9666ee865fd18ba9d59dca99aaa59eea431e600cc743d4aa8d

See more details on using hashes here.

Provenance

The following attestation bundles were made for gestaltdb-0.3.0-py3-none-any.whl:

Publisher: publish.yml on mylonasc/gestaltdb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.5.2

2 files

0.5.1

2 files

This release

0.3.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page