We built a type-safe Python ORM for RedisGraph/FalkorDB
We built a type-safe Python ORM for RedisGraph/FalkorDB
We were tired of writing raw Cypher — escaping quotes, zero autocomplete, refactoring nightmares — so we built GraphORM: a type-safe Python ORM for RedisGraph/FalkorDB using pure Python objects. What it does Instead of fragile Cypher: query = """ MATCH (a:User {user_id: 1})-[r1:FRIEND]->(b:User)-[r2:FRIEND]->(c:User) WHERE c.user_id <> 1 AND b.active = true WITH b, count(r2) as friend_count WHERE friend_count > 5 RETURN c, friend_count ORDER BY friend_count DESC LIMIT 10 """ You write type-safe Python: stmt = select().match( (UserA, FRIEND.alias("r1"), UserB), (UserB, FRIEND.alias("r2"), UserC) ).where( (UserA.user_id == 1) & (UserC.user_id != 1) & (UserB.active == True) ).with_( UserB, count(FRIEND.alias("r2")).label("friend_count") ).where( count(FRIEND.alias("r2")) > 5 ).returns( UserC, count(FRIEND.alias("r2")).label("friend_count") ).orderby( count(FRIEND.alias("r2")).desc() ).limit(10) Key features: • Type-safe schema with Python type hints • Fluent query builder (select().match().where().returns()) • Automatic batching (flush(batch_size=1000)) • Atomic transactions (with graph.transaction(): ...) • Zero string escaping — O'Connor and "The Builder" just work Target audience • AI/LLM agent devs: store long-term memory as graphs (User → Message → ToolCall) • Web crawler engineers: insert 10k pages + links in 12 lines vs 80 lines of Cypher • Social network builders: query "friends of friends" with indegree()/outdegree() • Data engineers: track lineage (Dataset → Transform → Output) • Python devs new to graphs: avoid Cypher learning curve Data insertion: the real game-changer Raw Cypher nightmare: queries = [ """CREATE (:User {email: "alice@example.com", name: "Alice O\\'Connor"})""", """CREATE (:User {email: "bob@example.com", name: "Bob \\"The Builder\\""})""" ] for q in queries: graph.query(q) # No transaction safety! GraphORM bliss: alice = User(email="alice@example.com", name="Alice O'Connor") bob = User(email="bob@example.com", name='Bob "The Builder"') graph.add_node(alice) graph.add_edge(Follows(alice, bob, since=1704067200)) graph.flush() # One network call, atomic transaction Try it in 30 seconds pip install graphorm from graphorm import Node, Edge, Graph class User(Node): __primary_key__ = ["email"] email: str name: str class Follows(Edge): since: int graph = Graph("social", host="localhost", port=6379) graph.create() alice = User(email="alice@example.com", name="Alice") bob = User(email="bob@example.com", name="Bob") graph.add_node(alice) graph.add_edge(Follows(alice, bob, since=1704067200)) graph.flush() GitHub: https://github.com/hello-tmst/graphorm We'd love honest feedback: • Does this solve a real pain point for you? • What's missing for production use? • Any API design suggestions?
Share cardActual performance
Launch Intel predictions
Analyze your own launch →Incorrect prediction on native model
Similar products
Rescue – type-safe exceptions for Python
I wrote a safe templating langage POC for python
A sum-type decorator for python
I made type-safe Firestore ORM and call it Typesaurus
C8x type safe K8s deployments
Newzly-phantom – Asynchronous type-safe Scala DSL for Cassandra
I built type-safe dynamic arrays for C after struggling with stb_ds.h
A Python with Hindley-Milner-like type annotations, compiling to C
Math Type for Python
Type-Safe alternative to stdio.h for C