First Steps¶
This guide will walk you through the basics of using AnyModel to manage your domain entities with various storage backends.
Installation¶
Install anymodel using your preferred package manager:
pip install anymodel
Or with uv:
uv add anymodel
Basic Concepts¶
AnyModel is built around several key concepts that work together to provide a clean data mapping solution:
Entity - Your domain objects that extend Pydantic’s BaseModel with state tracking
Mapper - Handles persistence operations between entities and storage
Storage - Backend implementations (memory, filesystem, SQL)
Collection - Type-safe collections of entities
Relations - Lazy-loaded relationships between entities
Creating Your First Entity¶
Entities are Pydantic models that inherit from Entity. They automatically track their state (transient, dirty, or clean) and can be persisted to storage:
from anymodel import Entity, Field
from datetime import datetime
class Task(Entity):
title: str
description: str = ""
completed: bool = False
created_at: datetime = Field(default_factory=datetime.now)
The Field function is re-exported from SQLModel and provides all Pydantic field configuration options plus SQL-specific features.
Setting Up Storage and Mapper¶
AnyModel supports multiple storage backends. Let’s start with the simplest one - in-memory storage:
from anymodel import Mapper, MemoryStorage
# Create storage instance
storage = MemoryStorage()
# Create mapper for your entity
task_mapper = Mapper(Task, storage)
The mapper handles all CRUD operations and maintains an identity map to prevent duplicate instances.
Basic Operations¶
Creating and Saving Entities¶
# Create a new task
task = Task(
title="Learn HDM",
description="Read the documentation and try examples"
)
# Save to storage
task_mapper.save(task)
print(f"Task saved with ID: {task.pk}")
Finding Entities¶
# Find by primary key
task = task_mapper.find_one_by_pk("task-id-here")
# Find all tasks
all_tasks = task_mapper.find()
# Find with filters (storage-specific)
completed_tasks = task_mapper.find({"completed": True})
Updating Entities¶
Entities automatically track changes. Simply modify the entity and save:
task = task_mapper.find_one_by_pk(task_id)
task.completed = True
task_mapper.save(task) # Only updates changed fields
Deleting Entities¶
task = task_mapper.find_one_by_pk(task_id)
task_mapper.delete(task)
Working with Collections¶
Collections provide a type-safe way to work with groups of entities:
from anymodel import Collection
class Project(Entity):
name: str
tasks: Collection[Task] = Collection()
project = Project(name="My Project")
project.tasks.append(Task(title="First task"))
project.tasks.append(Task(title="Second task"))
# Collections are iterable
for task in project.tasks:
print(task.title)
Entity Relations¶
AnyModel supports lazy-loaded relations between entities:
from anymodel import OneToManyRelation
class Author(Entity):
name: str
posts: OneToManyRelation["Post"] = OneToManyRelation()
class Post(Entity):
title: str
content: str
author_id: str
# Relations are loaded on demand
author = author_mapper.find_one_by_pk(author_id)
author_mapper.load(author, "posts") # Explicitly load relation
for post in author.posts:
print(post.title)
Using Different Storage Backends¶
Filesystem Storage¶
Store entities as JSON files:
from anymodel.storages.filesystem import FileSystemStorage
storage = FileSystemStorage(directory="./data")
mapper = Mapper(Task, storage)
SQL Storage¶
Use SQLAlchemy for relational databases:
from anymodel.storages.sqlalchemy import SqlAlchemyStorage
from sqlalchemy import create_engine
engine = create_engine("sqlite:///tasks.db")
storage = SqlAlchemyStorage(engine)
mapper = Mapper(Task, storage)
Next Steps¶
Read the Core Concepts guide for deeper understanding
Explore the API reference for anymodel.types and anymodel.storages
Check out the examples in the repository for real-world usage patterns