Skip to main content

A Python ORM for Apache AGE graph database

Project description

age-orm

A Python ORM for Apache AGE, providing SQLAlchemy-like abstractions for graph database operations.

Status: v0.1.0 — Core implemented (models, CRUD, query builder, relationships, async)

Features

Core

  • Pydantic v2-based model definitions for vertices and edges
  • Graph, Vertex, and Edge abstractions
  • Automatic schema creation (labels, indexes)
  • CRUD operations (create, read, update, delete)
  • Connection pooling via psycopg3

Query Building

  • Fluent Cypher query builder (filter, sort, limit, skip)
  • Safe parameter substitution
  • Raw Cypher support
  • Bulk mutations (update/delete via query)

Advanced

  • Sync + Async support (psycopg3's unified API)
  • Relationship descriptors with lazy loading
  • Event system (pre/post hooks for add, update, delete)
  • Bulk import (direct SQL INSERT for performance)
  • Graph traversal helpers (expand, traverse)
  • Dirty tracking (only update changed fields)
  • Migrations and schema versioning
  • Integration with AGEFreighter for bulk loads

Installation

# With uv
uv add age-orm

# With pip
pip install age-orm

Requires Python 3.12+ and a running Apache AGE instance.

Quick Start

from age_orm import Database, Vertex, Edge, relationship

# Define models
class Person(Vertex):
    __label__ = "Person"
    name: str
    age: int
    email: str | None = None

class Knows(Edge):
    __label__ = "KNOWS"
    since: int
    relationship_type: str = "friend"

# Connect
db = Database("postgresql://ageuser:agepassword@localhost:5433/agedb")
graph = db.graph("social", create=True)

# Create vertices
alice = Person(name="Alice", age=30)
bob = Person(name="Bob", age=25)
graph.add(alice)
graph.add(bob)

# Create edge
knows = Knows(since=2020)
graph.connect(alice, knows, bob)

# Query
people = graph.query(Person).filter("n.age > $min_age", min_age=20).sort("n.name").all()
alice = graph.query(Person).filter_by(name="Alice").one()

# Traverse
friends = graph.traverse(alice, "KNOWS", depth=2, target_class=Person)

# Raw Cypher
results = graph.cypher(
    "MATCH (n:Person)-[:KNOWS]->(m) RETURN n.name, m.name",
    columns=["a", "b"]
)

# Cleanup
db.close()

Async Usage

from age_orm import AsyncDatabase

async with AsyncDatabase("postgresql://...") as db:
    graph = await db.graph("social", create=True)
    alice = Person(name="Alice", age=30)
    await graph.add(alice)

    q = await graph.query(Person)
    people = await q.filter("n.age > $min", min=20).all()

Relationships

class Person(Vertex):
    __label__ = "Person"
    name: str
    friends: list["Person"] = relationship("Person", "KNOWS", direction="outbound")
    employer: "Company" = relationship("Company", "WORKS_AT", uselist=False)

Relationships are lazy-loaded on access when the entity is bound to a graph.

Event Hooks

from age_orm import listen, listens_for

@listens_for(Person, "pre_add")
def validate_person(target, event, **kwargs):
    if target.age < 0:
        raise ValueError("Age cannot be negative")

Dependencies

  • psycopg[binary,pool] >= 3.2 — PostgreSQL driver with connection pooling
  • pydantic >= 2.3 — Data validation and models

Project Structure

age_orm/
├── __init__.py           # Public API exports
├── exceptions.py         # Custom exceptions
├── event.py              # Event system (pre/post hooks)
├── database.py           # Connection + pool management
├── graph.py              # Graph class + CRUD + traversal
├── references.py         # Relationship descriptors
├── models/
│   ├── base.py           # AgeModel base class
│   ├── vertex.py         # Vertex model
│   └── edge.py           # Edge model
├── query/
│   └── builder.py        # Cypher query builder
└── utils/
    └── serialization.py  # Agtype serialization helpers

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

age_orm-0.2.0.tar.gz (28.7 kB view details)

Uploaded Source

Built Distribution

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

age_orm-0.2.0-py3-none-any.whl (23.7 kB view details)

Uploaded Python 3

File details

Details for the file age_orm-0.2.0.tar.gz.

File metadata

  • Download URL: age_orm-0.2.0.tar.gz
  • Upload date:
  • Size: 28.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for age_orm-0.2.0.tar.gz
Algorithm Hash digest
SHA256 1e9c86b192f5e440d37a513c666bc734463366e39884240a6628d4cf4c5f7809
MD5 d87db0ba1bbdcd755e9ade1002260509
BLAKE2b-256 9e4a2dc27e68a684c0ab2917862cb29ffe054ae89128c088712e19f6000ce5ca

See more details on using hashes here.

File details

Details for the file age_orm-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: age_orm-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 23.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for age_orm-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3a976e5482cdcb11f212bc083ba421af8a5097c1dadd0180123192623977ec00
MD5 e89c8fe755bb01d96980fcd35afbf483
BLAKE2b-256 fa2909d0620f7319c3fff18e06e50c63a28b561a1fbcb8e429d5d20587d7ac6c

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