Skip to main content

Pydantic-based OGM (Object-Graph Mapping) for Uni Graph Database

Project description

uni-pydantic

Pydantic-based OGM (Object-Graph Mapping) for the Uni Graph Database.

PyPI License

Features

  • Type Safety: Full IDE autocomplete and type checking for graph operations.
  • Pydantic v2: Leverage Pydantic's validation, computed fields, and serialization.
  • Schema-from-Models: Auto-generate Uni schema from Pydantic model definitions.
  • Relationships: Edges as declarative fields with direction support.
  • Query DSL: Type-safe filter builder with raw Cypher escape hatch.
  • Vector Search: Built-in K-NN similarity search.
  • Lifecycle Hooks: @before_create, @after_create decorators.

Installation

pip install uni-pydantic

Quick Start

import uni_db
from uni_pydantic import UniNode, UniEdge, UniSession, Field, Relationship, Vector

# Define models
class Person(UniNode):
    __label__ = "Person"

    name: str
    age: int | None = None
    email: str = Field(unique=True, index="btree")
    embedding: Vector[128] = Field(metric="cosine")

    friends: list["Person"] = Relationship("FRIEND_OF", direction="both")


class Company(UniNode):
    __label__ = "Company"

    name: str = Field(unique=True)


class WorksAt(UniEdge):
    __edge_type__ = "WORKS_AT"
    __from__ = Person
    __to__ = Company

    role: str = "engineer"


# Connect and sync schema
db = uni_db.Uni("./my_graph")
session = UniSession(db)
session.register(Person, Company, WorksAt)
session.sync_schema()

# Create
alice = Person(name="Alice", age=30, email="alice@example.com")
session.add(alice)
session.commit()

# Query with DSL
adults = (
    session.query(Person)
    .filter(Person.age >= 18)
    .order_by(Person.name)
    .limit(10)
    .all()
)

# Vector search
similar = (
    session.query(Person)
    .vector_search("embedding", query_vector, k=10)
    .all()
)

Model Definition

Nodes

from uni_pydantic import UniNode, Field, Vector

class Article(UniNode):
    __label__ = "Article"      # optional — defaults to class name

    title: str
    slug: str = Field(index="btree", unique=True)
    views: int = Field(default=0)
    tags: list[str] = Field(default_factory=list)
    embedding: Vector[768] = Field(metric="cosine")

Edges

from uni_pydantic import UniEdge

class Authored(UniEdge):
    __edge_type__ = "AUTHORED"
    __from__ = Person
    __to__ = Article

    role: str = "primary"

Relationships

class Person(UniNode):
    follows:   list["Person"]        = Relationship("FOLLOWS")
    followers: list["Person"]        = Relationship("FOLLOWS", direction="incoming")
    friends:   list["Person"]        = Relationship("FRIEND_OF", direction="both")
    manager:   "Person | None"       = Relationship("REPORTS_TO")

Query DSL

# Filter
people = session.query(Person).filter(Person.name == "Alice").all()

# Chained
results = (
    session.query(Person)
    .filter(Person.age >= 18)
    .order_by(Person.name, descending=True)
    .limit(10)
    .skip(20)
    .all()
)

# Filter helpers
Person.name.starts_with("A")
Person.name.contains("lic")
Person.age.in_([25, 30, 35])
Person.email.is_null()
Person.email.is_not_null()

# Vector search
similar = (
    session.query(Person)
    .vector_search("embedding", query_vec, k=10)
    .all()
)

CRUD

# Create
person = Person(name="Bob", age=25)
session.add(person)
session.commit()

# Bulk
session.add_all([Person(name=f"User{i}") for i in range(100)])
session.commit()

# Update
person.age = 26
session.commit()

# Delete
session.delete(person)
session.commit()

Lifecycle Hooks

from datetime import datetime
from uni_pydantic import before_create, after_create

class Person(UniNode):
    name: str
    created_at: datetime | None = None

    @before_create
    def set_created_at(self):
        self.created_at = datetime.now()

    @after_create
    def log_creation(self):
        print(f"Created: {self.name}")

Raw Cypher

results = session.cypher(
    "MATCH (p:Person)-[:FRIEND_OF]->(f:Person) WHERE p.name = $name RETURN f",
    params={"name": "Alice"},
    result_type=Person,
)

Async

from uni_pydantic import AsyncUniSession

session = AsyncUniSession(db)
await session.sync_schema()

alice = Person(name="Alice", email="alice@example.com")
session.add(alice)
await session.commit()

results = await session.query(Person).filter(Person.age >= 18).all()

Links

License

Apache-2.0

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

uni_pydantic-2.4.1.tar.gz (200.2 kB view details)

Uploaded Source

Built Distribution

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

uni_pydantic-2.4.1-py3-none-any.whl (44.8 kB view details)

Uploaded Python 3

File details

Details for the file uni_pydantic-2.4.1.tar.gz.

File metadata

  • Download URL: uni_pydantic-2.4.1.tar.gz
  • Upload date:
  • Size: 200.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.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":true}

File hashes

Hashes for uni_pydantic-2.4.1.tar.gz
Algorithm Hash digest
SHA256 ae593979a562e951ce573353c258fa2344ae2eaa4ecbd15a4f41848bf76da34c
MD5 ef5f54c4d5a4b108774f1d92ecde6474
BLAKE2b-256 6fee5bbfdd5c8238c1f746518f2d97a2813f005644f302bd1b60a366fb069617

See more details on using hashes here.

File details

Details for the file uni_pydantic-2.4.1-py3-none-any.whl.

File metadata

  • Download URL: uni_pydantic-2.4.1-py3-none-any.whl
  • Upload date:
  • Size: 44.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.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":true}

File hashes

Hashes for uni_pydantic-2.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 fd2e5847907a35fe77f42dd9094efc523f3270bfbf3b988c8a1a6ac2e1e2845b
MD5 e7f4e918dae96199674a3b0e2cf6eed2
BLAKE2b-256 dd2c5cbc5be03136b46e74e4c18b4613cbabd44319534a11b44c3858c95cd1ea

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