Current collected state Current
Observed since 21 Oct, 09:01 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
A Python ORM for Apache AGE graph database
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)
# With uv
uv add age-orm
# With pip
pip install age-orm
Requires Python 3.12+ and a running Apache AGE instance.
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()
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()
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.
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")
psycopg[binary,pool] >= 3.2 — PostgreSQL driver with connection poolingpydantic >= 2.3 — Data validation and modelsage_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
MIT
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.2.0 | 22 Feb 2026 | 7 |
This describes our collected data; it is not a security assessment.
Observed since 21 Oct, 09:01 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:14829124589ad2b05a5f4922a1e798d47c62627fd113d8ca45cc4d6f526491aa