Skip to content

sillo.record: what it adds on top of Tortoise, how the two fit together, and a map of this section.

Record is Sillo’s ORM, and this manual is all of it.

from sillo.record import Model
from tortoise import fields
class Post(Model):
id = fields.IntField(pk=True)
title = fields.CharField(max_length=200)
body = fields.TextField()
post = await Post.create(title="Hello", body="…")
recent = await Post.active().order_by("-created_at").limit(10)
print(post.to_dict())

sillo.record is a convenience layer over Tortoise ORM. It does not fork Tortoise, wrap its query compiler, or replace its connection handling.

Every Tortoise feature (fields, querysets, Q objects, relations, prefetching, aggregation, raw SQL) behaves exactly as the Tortoise documentation describes, because it is Tortoise underneath.

You should not need to go and read that documentation. This section covers the whole surface: fields, relationships, the queryset API, the lookups, aggregation, eager loading and raw SQL, as Sillo exposes it, with the Record layer in place rather than described separately.

What Record adds is the layer Django and Laravel developers reach for on day one:

A base modelTimestamps and soft deletes already wired
Mass-assignment controlfillable and guarded
CastingAttributes converted on the way in and out
ScopesReusable query fragments, local and global
EventsLifecycle hooks and observers
CollectionsChainable operations on a result set
FactoriesTest data without fixtures
TransactionsA context manager, with savepoints
MigrationsGenerated, reviewable, and applied by the CLI
  • Setup: setup_record, and the connection lifecycle
  • Configuration: DatabaseConfig, URLs, backends, pooling

0.x shipped one inside the framework, under sillo.admin. 1.0 does not: it lives in Warder, a separate package with a React interface, installed with pip install warder when you want one and absent when you do not.

Some parts of this package are thinner than a first read suggests, and you are better served knowing which up front than finding out during an incident. Where that is true, the page says so plainly, including what a helper needs before it will do what its name says. See for example the encrypted cast.