Motor-ODM 0.1 Documentation¶
Overview¶
Motor-ODM is a modern async Object-Document-Mapper for MongoDB. It is based on
Pydantic and Motor. It exclusively
works with asyncio
.
Using ObjectId
¶
If you are using Pydantic for more than your ODM (e.g. when using FastAPI and want to
use the bson.ObjectId
class you need to tell Pydantic how to handle this class. You
can either do this manually or use the handlers from Motor-ODM. To do so all you need to do is make sure that
motor_odm.document
is imported before you define your Pydantic models that use
ObjectId
.
API-Documentation¶
Motor-ODM consists of several modules and classes all of which are documented in the full API reference. This section highlights some classes in order to give you an overview where to start.
This is the base class for all documents defined using Motor-ODM. |
|
Creates a MongoDB query from the specified arguments. |
Package motor_odm
¶
The motor_odm
package contains all modules for Motor-ODM.
Submodules¶
Module motor_odm.document
¶
This module contains the base class for interacting with Motor-ODM: Document
.
The Document
class is the main entry point to Motor-ODM and provides its main
interface.
-
class
motor_odm.document.
Document
(**data: Any)¶ Bases:
pydantic.main.BaseModel
This is the base class for all documents defined using Motor-ODM.
A
Document
is a pydantic model that can be inserted into a MongoDB collection. This class provides an easy interface for interacting with the database. Each document has anDocument.id
(named_id
in MongoDB) by default by which it can be uniquely identified in the database. The name of this field cannot be customized however you can override it if you don’t want to useObjectID
values for your IDs.- Parameters
abstract – Mark subclasses as
abstract
in order to create an abstract document. An abstract document cannot be instantiated but can be subclassed. This enables you to extract common functionality from multiple documents into a common abstract super-document.
-
classmethod
collection
() → motor.core.AgnosticCollection¶ Returns the collection for this
Document
.The collection uses the
codec_options
,read_preference
,write_concern
andread_concern
from the document’s`Mongo`
class.
-
async classmethod
count_documents
(filter: Mapping = None, *args: Any, **kwargs: Any) → int¶ Returns the number of documents in this class’s collection.
This method is filterable.
-
classmethod
db
() → motor.core.AgnosticDatabase¶ Returns the database that is currently associated with this document.
If no such database exists this returns the database of the parent document (its superclass). If no
Document
class had itsuse()
method called to set a db, anAttributeError
is raised.
-
async
delete
(*args: Any, **kwargs: Any) → bool¶ Deletes the document from the database.
This method does not modify the instance in any way.
args
andkwargs
are passed to motor’sdelete_one
method.- Returns
True
if the document was deleted.
-
async classmethod
delete_many
(*objects: GenericDocument) → int¶ Deletes all specified objects.
- Parameters
objects – All objects to be deleted.
- Returns
The number of documents deleted.
-
classmethod
find
(filter: DictStrAny = None, *args: Any, **kwargs: Any) → AsyncIterator[GenericDocument]¶ Returns an iterable over a cursor returning documents matching
filter
.args
andkwargs
are passed to motor’sfind
method.
-
async classmethod
find_one
(filter: DictStrAny = None, *args: Any, **kwargs: Any) → Optional[GenericDocument]¶ Returns a single document from the collection.
-
async classmethod
find_one_and_delete
(filter: DictStrAny = None, *args: Any, **kwargs: Any) → Optional[GenericDocument]¶ Finds a document and deletes it.
This method works exactly like pymongo’s find_one_and_delete except that this returns a
Document
instance.
-
async classmethod
find_one_and_replace
(filter: DictStrAny, replacement: Union[DictStrAny, GenericDocument], return_document: bool = False, *args: Any, **kwargs: Any) → Optional[GenericDocument]¶ Finds a document and replaces it.
This method works exactly like pymongo’s find_one_and_replace except that this returns a
Document
instance. Note that if you specifyreturn_document=ReturnDocument.AFTER
this method will reload thereplacement
document.
-
async classmethod
find_one_and_update
(filter: DictStrAny, update: DictStrAny, *args: Any, **kwargs: Any) → Optional[GenericDocument]¶ Finds a document and updates it.
This method works exactly like pymongo’s find_one_and_update except that this returns a
Document
instance.
-
async classmethod
init_indexes
(drop: bool = True, session: motor.core.AgnosticClientSession = None, **kwargs: Any) → None¶ Creates the indexes for this collection of documents.
The indexes are specified in the
indexes
field of theMongo
class. By default this method makes sure that after the coroutine completes the collection’s indexes equal the specified indexes. If you do not want to drop existing indexes you can specifydrop=True
as keyword argument. Note however that this method will always override existing indexes.- Parameters
drop – If
True
all indexes not specified by this collection will be dropped. Default isTrue
.session – A session to use for any database actions.
kwargs – Any keyword arguments are passed to the DB calls. This may be used to specify timeouts etc.
-
async
insert
(*args: Any, **kwargs: Any) → bool¶ Inserts the object into the database.
The object is inserted as a new object. If the document already exists this method will raise an error. Use
save()
instead if you want to update an existing value.
-
async classmethod
insert_many
(*objects: GenericDocument, **kwargs: Any) → None¶ Inserts multiple documents at once.
It is preferred to use this method over multiple
insert()
calls as the performance can be much better.
-
mongo
(*, include: Union[AbstractSetIntStr, DictIntStrAny] = None, exclude: Union[AbstractSetIntStr, DictIntStrAny] = None) → DictStrAny¶ Converts this object into a dictionary suitable to be saved to MongoDB.
-
async
reload
(*args: Any, **kwargs: Any) → bool¶ Reloads a document from the database.
Use this method if a model might have changed in the database and you need to retrieve the current version. You do not need to call this after inserting a newly created object into the database.
-
async
save
(upsert: bool = True, *args: Any, **kwargs: Any) → bool¶ Saves this instance to the database.
By default this method creates the document in the database if it doesn’t exist. If you don’t want this behavior you can pass
upsert=False
.Any
args
andkwargs
are passed to motor’sreplace_one
method.- Parameters
upsert – Whether to create the document if it doesn’t exist.
- Returns
True
if the document was inserted/updated,False
if nothing changed. This may also indicate that the document was not changed.
-
class
motor_odm.document.
Mongo
¶ Bases:
object
This class defines the defaults for collection configurations.
Each collection (defined by a subclass of
Document
) can override these using an inner class namedMongo
. Attributes are implicitly and transitively inherited from the Mongo classes of base classes.-
abstract
: bool = False¶ Whether the document is abstract.
The value for this field cannot be specified in the
Mongo
class but as a keyword argument on class creation.
-
codec_options
: Optional[bson.codec_options.CodecOptions] = None¶ The codec options to use when accessing the collection.
Defaults to the database’s
codec_options
.
-
collection
: Optional[str] = None¶ The name of the collection for a document. This attribute is required.
-
indexes
: List[pymongo.operations.IndexModel] = []¶ A list of indexes to create for the collection.
-
read_concern
: Optional[pymongo.read_concern.ReadConcern] = None¶ The read concern to use when accessing the collection.
Defaults to the database’s
read_concern
.
-
read_preference
: Optional[pymongo.read_preferences.ReadPreference] = None¶ The read preference to use when accessing the collection.
Defaults to the database’s
read_preference
.
-
write_concern
: Optional[pymongo.write_concern.WriteConcern] = None¶ The write concern to use when accessing the collection.
Defaults to the database’s
write_concern
.
-
Module motor_odm.encoders
¶
BSON encoders for common python types.
This module contains a collection of bson.codec_options.TypeEncoder
subclasses
for common python types such as sets. Note that these encoders are provided as a
convenience but are not used automatically. If you want to use sets in your documents
you have to provide the appropriate codec_options
to the MongoDB client, database,
collection or function.
-
class
motor_odm.encoders.
SetEncoder
¶ Bases:
bson.codec_options.TypeEncoder
BSON support for python
set
.This encoder encodes a
set
in form of alist
. The list is not converted back into a set automatically but if you are using theDocument
class this is done upon initialization of your model.-
python_type
¶ alias of
builtins.set
-
transform_python
¶ alias of
builtins.list
-
-
class
motor_odm.encoders.
FrozensetEncoder
¶ Bases:
bson.codec_options.TypeEncoder
BSON support for python
frozenset
.This encoder encodes a
frozenset
in form of alist
. The list is not converted back into a set automatically but if you are using theDocument
class this is done upon initialization of your model.-
python_type
¶ alias of
builtins.frozenset
-
transform_python
¶ alias of
builtins.list
-
Module motor_odm.fixtures
¶
This module contains patches for some frameworks to make Motor-ODM work as one would expect. Expect some more or less ugly hacks here…
Note that all patches are applied automatically at import time.
Module motor_odm.helpers
¶
This module contains various supporting functions that can be used independently of the Motor-ODM framework. Some of these utilities can be found in similar form in other packages or frameworks and are adapted here to reduce the number of dependencies.
-
motor_odm.helpers.
inherit_class
(name: str, self: Optional[T], parent: T, merge: Iterable[str] = None) → T¶ Performs a pseudo-inheritance by creating a new class that inherits from
self
andparents
. This is useful to support intuitive inheritance on inner classes (typically namedMeta
).Note that this method neither returns
self
nor any of theparents
but a new type that inherits from both.- Parameters
name – The name of the newly created type.
self – The primary base class (fields in this class take preference over the
parents
’ fields.parent – The secondary base class (a pseudo-parent of
self
).merge – A list of fields that should not be replaces during inheritance but merged. This only works for some types.
- Returns
A new type inheriting from
self
andparents
.
-
motor_odm.helpers.
merge_values
(value1: Any, value2: Any) → Any¶ Merges two values.
This method works only for specific collection types (namely lists, dicts and sets). For other values a
ValueError
is raised.The type of the resulting value is determined by the type of
value2
, howevervalue1
may override some of the contents invalue2
(e.g. replace values for dict keys).
-
motor_odm.helpers.
monkey_patch
(cls: Union[type, module], name: Optional[str] = None) → Callable[[C], C]¶ Monkey patches class or module by adding to it decorated function. Anything overwritten can be accessed via a
.original
attribute of the decorated object.- Parameters
cls – The class or module to be patched.
name – The name of the attribute to be patched.
- Returns
A decorator that monkey patches
cls.name
and returns the decorated function.
Module motor_odm.indexes
¶
-
class
motor_odm.indexes.
IndexManager
(collection: motor.core.AgnosticCollection, session: motor.core.AgnosticClientSession, **kwargs: Any)¶ Bases:
object
An
IndexManager
instance can create a specific state concerning indexes.Note
The
IndexManager
is used internally byDocument
. Normally there is no need to use this class manually.-
async
ensure_indexes
(indexes: Iterable[pymongo.operations.IndexModel], drop: bool = True) → None¶ Ensures that the specified
indexes
exist in the databse.This method communicates with the database several times to compare the specified
indexes
to the indexes already present in the database. If an index already exists it is not recreated. If an index exists with different options (name, uniqueness, …) it is dropped and recreated.Any indexes in the database that are not specified in
indexes
will be dropped unlessdrop=False
is specified.
-
static
equal
(index: pymongo.operations.IndexModel, db_index: bson.son.SON) → bool¶ Compares the specified
index
anddb_index
.This method return
True
if theindex
specification can be considered equal to the existingdb_index
in the database.
-
get_db_index
(spec: bson.son.SON) → Optional[bson.son.SON]¶ Fetches the database index matching the
spec
.This method does not communicate with the database. You have to have called
load_db_indexes()
before.- Returns
An index from the database or
None
if no index matchingspec
exists.
-
async
Module motor_odm.query
¶
-
class
motor_odm.query.
Query
(*args: Any, **kwargs: Any)¶ Bases:
dict
,typing.Generic
A MongoDB query.
Queries behave like ordinary dictionaries (in fact they inherit from
dict
). However they offer some additional convenience related to MongoDB queries. Most notably they can be constructed conveniently from keyword arguments. See the documentation onq()
for details.This class also offers some factory methods for special queries such as using a JSON Schema.
-
add_expression
(field: str, value: Any, op: str = None) → None¶ Adds a single expression to this query.
An expression is a constraint for a single field. This method modifies the query to add a constraint for the specified
field
to be equal tovalue
. Ifop
is specified it is used instead of the default$eq
operator.- Raises
KeyError – If
field
has already a value forop
that is not equal tovalue
.
-
comment
(comment: str) → motor_odm.query.Query¶ Adds a comment to this query.
-
classmethod
expr
(expression: dict) → motor_odm.query.Query¶ Constructs an
$expr
query.
-
extend
(**kwargs: DictStrAny) → None¶ Adds fields to this query.
This method adds the same keys and values that you would get using the
q()
function with only keyword arguments. See the documentation on that method for details.
-
classmethod
schema
(schema: DictStrAny) → Query¶ Constructs a
$jsonSchema
query.
-
classmethod
text
(search: str, language: str = None, case_sensitive: bool = None, diacritic_sensitive: bool = None) → motor_odm.query.Query¶ Constructs a
$text
query using the specified arguments.
-
classmethod
where
(where: Union[str, bson.code.Code]) → motor_odm.query.Query¶ Constructs a
$where
query.
-
-
motor_odm.query.
q
(*args: Any, **kwargs: Any) → motor_odm.query.Query¶ Creates a MongoDB query from the specified arguments.
The query can be used to filter documents in Motor-ODM or even directly in Motor or PyMongo. This function is the preferred way of constructing queries. You can use special keyword arguments to construct more complex queries.
One of the most common cases is a query by ID. Specify the ID as the only positional argument:
>>> q(123) {'_id': 123}
If you pass
None
as the single id value, a query will be constructed that matches nothing. >>> q(None) {‘X’: {‘$in’: []}}You can also create a query that matches an ID in a list of IDs by specifying multiple positional arguments, each of which will be treated as a possible ID. In this case
None
values will simply be ignored. >>> q(123, None, “ABC”) {‘_id’: {‘$in’: [123, ‘ABC’]}}Instead of querying the ID of a document you most likely need to filter documents based on their fields. You can do this by providing the respective keyword arguments. You can combine positional and keyword arguments if you need to. In the simples case we want to create a query that filters on the value of one or more fields:
>>> q(name="John", age=20) {'name': 'John', 'age': 20}
You can also use MongoDB query operators to create more complex queries:
>>> q(age__gt=20, age__lt=100) {'age': {'$gt': 20, '$lt': 100}}
Lastly you can combine queries with
&
,|
and^
. The^
operator means nor in this case.>>> (q(age=20) & q(name="John")) | q(age=21) {'$or': [{'$and': [{'age': 20}, {'name': 'John'}]}, {'age': 21}]}