Metadata-Version: 2.4
Name: tinydantic
Version: 0.2.0
Summary: A Pydantic-powered ODM (object-document mapper) for TinyDB
Keywords: odm,pydantic,tinydb
Author: Chris Wilson
Author-email: Chris Wilson <christopher.david.wilson@gmail.com>
License-Expression: Apache-2.0 OR MIT
License-File: LICENSES/Apache-2.0.txt
License-File: LICENSES/CC-BY-4.0.txt
License-File: LICENSES/MIT.txt
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: Pydantic :: 2
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Dist: pyyaml>=6.0
Requires-Dist: pydantic[email]>=2.11
Requires-Dist: tinydb>=4.8
Requires-Python: >=3.11
Project-URL: Changelog, https://github.com/tinydantic/tinydantic/blob/main/CHANGELOG.md
Project-URL: Documentation, https://tinydantic.dev
Project-URL: Issues, https://github.com/tinydantic/tinydantic/issues
Project-URL: Source, https://github.com/tinydantic/tinydantic
Description-Content-Type: text/markdown

# tinydantic

<!-- overview-start -->

[![PyPI - Version](https://img.shields.io/pypi/v/tinydantic.svg)](https://pypi.org/project/tinydantic) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/tinydantic.svg)](https://pypi.org/project/tinydantic) [![Pydantic v2](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/pydantic/pydantic/main/docs/badge/v2.json)](https://pydantic.dev)

`tinydantic` is a simple Python object-document mapper (ODM) for the [TinyDB](https://tinydb.readthedocs.io/en/latest/) document database. It uses [Pydantic](https://docs.pydantic.dev/latest/)—the most widely used data validation library—for document model definition and validation.

<!-- prettier-ignore-start -->

> [!NOTE]
> `tinydantic` is under active development. Releases follow the [SemVer versioning spec](https://semver.org):
>
> > Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.
>
> Minor releases may include breaking changes until v1.0 — check the [changelog](https://github.com/tinydantic/tinydantic/blob/main/CHANGELOG.md) when upgrading. Feedback is welcome!

<!-- prettier-ignore-end -->

<!-- overview-end -->

Full documentation is available at [tinydantic.dev](https://tinydantic.dev).

## Table of Contents

- [Installation](#installation)
- [Introduction](#introduction)
- [Basic Example](#basic-example)
- [License](#license)

## Introduction

<!-- introduction-start -->

`tinydantic` is a wrapper library around [TinyDB](https://tinydb.readthedocs.io/en/latest/) that enables using [Pydantic](https://docs.pydantic.dev/) models to manage documents stored in a TinyDB database. By specifying Python type annotations for each field in a document model, data validation is handled automatically by Pydantic when instantiating a model from the database.

<!-- introduction-end -->

## Installation

<!-- installation-start -->

`tinydantic` is [available on PyPI](https://pypi.org/project/tinydantic/) and can be installed with [pip](https://github.com/pypa/pip). Easy peasy lemon squeezy 🍋

```sh
pip install tinydantic
```

<!-- installation-end -->

## Basic Example

<!-- basic-example-start -->

Here's a basic example showing how to create, insert, and query for a document using `tinydantic`.

### Using `tinydantic` models

First, create a TinyDB database where the documents will be stored. In this example, we're using an in-memory database, but TinyDB supports other [storage types](https://tinydb.readthedocs.io/en/latest/usage.html#storage-types) which can store the database persistently as JSON, YAML, etc.

```pycon
>>> from tinydb import TinyDB
>>> from tinydb.storages import MemoryStorage
>>> db = TinyDB(storage=MemoryStorage)

```

Create a `User` document model, configuring it to store documents in the `users` table of the `db` database.

> [!TIP]
>
> Since `User` is a subclass of [TinydanticModel][tinydantic.TinydanticModel] (which itself is a subclass of [pydantic.BaseModel][]), `User` is also a Pydantic model! You have all the power of Pydantic models when creating a `tinydantic` document model.

```pycon
>>> from pydantic import EmailStr
>>> from tinydantic import TinydanticModel
>>> class User(TinydanticModel, database=db, table_name='users'):
...     name: str
...     email: EmailStr

```

Create a new `User` instance for a user named "Alice".

```pycon
>>> alice = User(name='Alice', email='alice@example.com')

```

Insert `alice` into the database.

```pycon
>>> alice.insert()
User(id=1, name='Alice', email='alice@example.com')

```

Query the database for users with the name "Alice". Notice that this returns a `User` instance that was automatically validated by Pydantic!

```pycon
>>> User.get(User.name == 'Alice')
User(id=1, name='Alice', email='alice@example.com')

```

### Comparison to TinyDB

Since `tinydantic` is built on top of TinyDB, you can still use `tinydb` to interact with the database directly if needed.

For comparison, let's try to accomplish the same task as shown above using only TinyDB _without_ `tinydantic`. For this example, we'll continue using the same database (`db`) we created earlier.

```pycon
>>> users_table = db.table('users')
>>> users_table.insert({'name': 'Bob', 'email': 'bob@example.com'})
2
>>> from tinydb import where
>>> users_table.get(where('name') == 'Bob')
{'name': 'Bob', 'email': 'bob@example.com'}

```

Notice, that TinyDB does not impose any restrictions on the document we insert _into_ the database table. Additionally, there is no automatic parsing or validation of the data _returned_ from the database.

### Pydantic validation in action

_What happens if an invalid document is somehow returned from the database?_

Let's set up a contrived example to test the automatic Pydantic validation.

First, we'll manually insert a document that is missing the `email` field from the `User` model we created earlier.

```pycon
>>> users_table.insert({'name': 'Carol'})
3

```

Next, we'll query for users named "Bob" using the tinydantic model we created earlier.

```pycon
>>> User.get(User.name == 'Carol')
Traceback (most recent call last):
  ...
pydantic_core._pydantic_core.ValidationError: 1 validation error for User
email
  Field required [type=missing, input_value={'name': 'Carol'}, input_type=Document]
```

As you can see, Pydantic produced a `ValidationError` because the document returned from the database is missing the `email` field required by the `User` model.

<!-- basic-example-end -->

## License

See the [LICENSE](https://github.com/tinydantic/tinydantic/blob/main/LICENSE.md) file for copyright & license information.
