Skip to main content
Firestore subcollections are collections that live under a specific document rather than at the root of the database. A common pattern is storing a user’s posts at users/{uid}/posts or a post’s comments at users/{uid}/posts/{pid}/comments. Firestore Pydantic ODM gives you first-class support for this hierarchy through the Settings.parent attribute, path-aware query methods, and a SubCollectionAccessor convenience wrapper.

Declaring a Subcollection

To declare a subcollection model, add a parent attribute to the model’s inner Settings class and point it at the parent model type. Leave parent unset (or absent) for top-level collections.

How Paths Resolve

The ODM builds the full Firestore path at runtime by walking the Settings.parent chain. Given the models above: No manual path construction is needed — the ODM calls _resolve_collection_ref() internally every time a CRUD method is invoked.

Creating Subcollection Documents

Pass the parent instance to save() when creating a subcollection document. The parent must already have an id (i.e. it must have been saved first).
After a successful save(), the ODM stores the resolved parent document path in post._parent_path. Any subsequent update() or delete() call on the same instance no longer requires parent= because the path is already known.

Querying a Subcollection

All read methods accept an optional parent= argument that scopes the query to the documents under that specific parent document.

find() with a parent

find_one() with a parent

get() by document ID

Updating and Deleting Subcollection Documents

Once an instance has _parent_path set (either from save() or find()), updates and deletes work without a parent= argument.

Cascade Delete

Calling delete(cascade=True) on a document first recursively deletes all subcollection documents under it, then deletes the document itself. The ODM discovers child models by inspecting _registered_models — every model whose Settings.parent points to the current class is considered a child.
Cascade delete requires all models to be registered via init_firestore_odm(). If you use per-model initialize_db() without populating BaseFirestoreModel._registered_models, child models will not be discovered and only the target document will be deleted.

SubCollectionAccessor

SubCollectionAccessor is a convenience wrapper that binds a parent instance to a child model class, giving you a clean object-oriented API for subcollection operations. Access it via parent_instance.subcollection(ChildModel):
SubCollectionAccessor validates at construction time that ChildModel.Settings.parent matches the type of the parent instance. Passing a mismatched pair raises a ValueError immediately.

Collection Group Queries

A collection group query runs across all subcollections with the same name, regardless of which parent document they live under. Use collection_group_find() when you need to search data without knowing — or caring about — the parent.
Collection group queries require a composite index in Firestore. If Firestore returns an index error the first time you run a collection group query, follow the link in the error message to create the index in the Firebase console.

_parent_path Tracking

The _parent_path private attribute records the full Firestore document path of the parent (e.g. "users/abc123") on each subcollection instance. It is set automatically in four situations:
  • After save(parent=...) — the resolved parent path is stored on the instance.
  • After find(parent=...) or find_one(parent=...) — every yielded instance has _parent_path set.
  • After get(doc_id, parent=...) — the returned instance has _parent_path set.
  • After collection_group_find() — the parent path is extracted from the document reference path.
Once _parent_path is stored, you can call update() and delete() on the instance without supplying parent= again:

Full Example

Models

Define Firestore document schemas and configure collection settings.

Database Client

Configure credentials, the emulator, and register your models.