A Pydantic-based Neo4j ORM with async/sync support
Project description
neo4pydantic
A Pydantic-based Neo4j ORM with async/sync support.
Overview
neo4pydantic provides an easy way to define Neo4j nodes and relationships as Pydantic models, and interact with a Neo4j database using both synchronous and asynchronous clients. It supports automatic type conversion, unique and indexed fields, and convenient CRUD operations.
Features
- Define Neo4j nodes and relationships as Pydantic models
- Sync and async client support
- Automatic type conversion for Neo4j temporal types
- Unique and indexed field support for efficient queries
- Simple CRUD operations for nodes and relationships
Installation
pip install neo4pydantic
Quick Start
1. Define Your Models
from neo4pydantic import BaseNode, BaseRelationship
class Person(BaseNode):
__label__ = "Person"
__unique_fields__ = ["email"]
name: str
email: str
age: int | None = None
city: str | None = None
class Company(BaseNode):
__label__ = "Company"
__unique_fields__ = ["name"]
name: str
industry: str | None = None
founded_year: int | None = None
class WorksAt(BaseRelationship):
__type__ = "WORKS_AT"
position: str
start_date: str | None = None
salary: int | None = None
2. Synchronous Usage
from neo4pydantic import Neo4jClient
client = Neo4jClient(uri="bolt://localhost:7687", user="neo4j", password="your_password")
with client.session() as session:
person = Person(name="John Doe", email="john@example.com", age=30, city="New York").save(session)
company = Company(name="Tech Corp", industry="Technology", founded_year=2010).save(session)
relationship = WorksAt(position="Software Engineer", start_date="2023-01-15", salary=75000)
relationship.save(session, person, company)
# Query
people = Person.find_by(session, city="New York")
3. Asynchronous Usage
Note that all asynchronous usage is the same as synchronous function
import asyncio
from neo4pydantic.async_ import AsyncNeo4jClient, BaseNode, BaseRelationship
async def main():
client = AsyncNeo4jClient(uri="bolt://localhost:7687", user="neo4j", password="your_password")
async with client.session() as session:
person = Person(name="Jane Doe", email="jane@example.com", age=28, city="San Francisco")
person = await person.save(session)
company = Company(name="Startup Inc", industry="Technology", founded_year=2020)
company = await company.save(session)
relationship = WorksAt(position="Senior Developer", start_date="2023-03-01", salary=90000)
await relationship.save(session, person, company)
# Query
people = await Person.find_by(session, city="San Francisco")
asyncio.run(main())
Querying and Advanced Usage
Find Multiple Nodes (find_by)
# Find all people in New York
people = Person.find_by(session, city="New York")
for person in people:
print(person)
Find a Single Node (find_one_by)
# Find a person by email
john = Person.find_one_by(session, email="john@example.com")
print(john)
Delete A Node (find_one_by)
# Delete a person
john = Person(id=10, mail="john@example.com").delete(session)
Automatically create indexes when startup
from neo4pydantic import IndexManager, Neo4jClient
client = Neo4jClient(uri="bolt://localhost:7687", user="neo4j", password="your_password")
def init_indexes():
# Import your custom model here so that the IndexManger can acknowledge your model before create the indexes
from your_custom_model import Person, Company, WorkFor
client.connect()
created_indexes = IndexManager(client.get_driver()).sync_indexes()
print(created_indexes)
Create Relationship with Custom Parameters (save_with_custom_params)
relationship = WorksAt(position="Junior Developer", start_date="2022-03-01", salary=90000)
relationship.save_with_custom_params(
session,
from_node_label=person.get_label(),
to_node_label=company.get_label(),
from_node_params={"email": person.email},
to_node_params={"name": company.name},
)
Directory Structure
neo4pydantic/sync/- Synchronous client and base classesasync_/- Asynchronous client and base classescore/- Core logic and base modelsutils/- Type conversion utilitiesexamples/- Example scripts for sync and async usage
tests/- Unit tests
Requirements
- Python 3.8+
- Neo4j 5.x
- Pydantic 2.x
License
MIT License © 2025 Edward Chu
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file neo4pydantic-0.1.1.tar.gz.
File metadata
- Download URL: neo4pydantic-0.1.1.tar.gz
- Upload date:
- Size: 17.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ba82476863d533f7166484f45eaa51af9a14b3905ff316055f5e2afcf2d5525
|
|
| MD5 |
c3d482d85cc872ca51c7e3839b5761f0
|
|
| BLAKE2b-256 |
ecbec1ee38bf5275d1faa6282021ad671f370c620897031e64000eac8d2bff64
|
File details
Details for the file neo4pydantic-0.1.1-py3-none-any.whl.
File metadata
- Download URL: neo4pydantic-0.1.1-py3-none-any.whl
- Upload date:
- Size: 17.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38122c072677ba7e641bd5cb24671d684714ec8acc0ab39e661f0d1778f6081d
|
|
| MD5 |
0be77cdb931fcdb22b73d5b02a9a255d
|
|
| BLAKE2b-256 |
99fddd94611089ac50aec099c1e70210cf831c539f47e051164ff3845f91e851
|