Engine¶
Creating the engine¶
In the previous examples, we created the engine using default parameters:
-
MongoDB: running on
localhost
port27017
-
Database name:
test
It's possible to provide a custom
AsyncIOMotorClient
to the AIOEngine constructor. In the same way, the database
name can be changed using the database
keyword argument.
1 2 3 4 5 6 |
|
For additional information about the MongoDB connection strings, see this section of the MongoDB documentation.
Usage with DNS SRV records
If you decide to use the DNS Seed List Connection
Format
(i.e mongodb+srv://...
), you will need to install the
dnspython package.
Create¶
There are two ways of persisting instances to the database (i.e creating new documents):
-
AIOEngine.save: to save a single instance
-
AIOEngine.save_all: to save multiple instances at once
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Resulting documents in the player
collection
{
"_id": ObjectId("5f85f36d6dfecacc68428a46"),
"game": "World of Warcraft",
"name": "Leeroy Jenkins"
}
{
"_id": ObjectId("5f85f36d6dfecacc68428a47"),
"game": "Counter-Strike",
"name": "Shroud"
}
{
"_id": ObjectId("5f85f36d6dfecacc68428a49"),
"game": "Starcraft",
"name": "TLO"
}
{
"_id": ObjectId("5f85f36d6dfecacc68428a48"),
"game": "Starcraft",
"name": "Serral"
}
Referenced instances
When calling AIOEngine.save or AIOEngine.save_all, the referenced models will be persisted as well.
Upsert behavior
The save
and save_all
methods behave as upsert operations (more
details). Hence, you might overwrite documents if you save
instances with an existing primary key already existing in the database.
Read¶
Examples database content
The next examples will consider that you have a player
collection populated with
the documents previously created.
Fetch a single instance¶
As with regular MongoDB driver, you can use the
AIOEngine.find_one method to get at most one
instance of a specific Model. This method will either return an instance matching the
specified criteriums or None
if no instances have been found.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Missing values in documents
While parsing the MongoDB documents into Model instances, ODMantic will use the provided default values to populate the missing fields.
See this section for more details about document parsing.
Fetch using sort
We can use the sort
parameter to fetch the Player
instance with
the first name
in ascending order:
await engine.find_one(Player, sort=Player.name)
sort
in the dedicated section.
Fetch multiple instances¶
To get more than one instance from the database at once, you can use the AIOEngine.find method.
This method will return an AIOCursor object, that can be used in two different ways.
Usage as an async iterator¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Ordering instances
The sort
parameter allows to order the query in ascending or descending order on
a single or multiple fields.
engine.find(Player, sort=(Player.name, Player.game.desc()))
sort
in the dedicated section.
Usage as an awaitable¶
Even if the async iterator usage should be preferred, in some cases it might be required to gather all the documents from the database before processing them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Pagination
You can as well use the skip
and limit
keyword arguments when using
AIOEngine.find, respectively to skip a specified
number of instances and to limit the number of fetched instances.
Referenced instances
When calling AIOEngine.find or AIOEngine.find_one, the referenced models will be recursively resolved as well.
Passing the model class to find
and find_one
When using the method to retrieve instances from the database, you have to specify the Model you want to query on as the first positional parameter. Internally, this enables ODMantic to properly type the results.
Count instances¶
You can count instances in the database by using the AIOEngine.count method. It's possible as well to use this method with filtering queries.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Combining multiple queries in read operations
While using find, find_one or count, you may pass as many queries as you want as positional arguments. Those will be implicitly combined as single and_ query.
Update¶
Updating an instance in the database can be done simply by modifying the instance locally and saving it again to the database.
The AIOEngine.save and
AIOEngine.save_all methods are actually behaving as
upsert
operations. In other words, if the instance already exists it will be updated.
Otherwise, the related document will be created in the database.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Resulting documents in the player
collection
{
"_id": ObjectId("5f85f36d6dfecacc68428a46"),
"game": "World of Warcraft",
"name": "Leeroy Jenkins"
}
{
"_id": ObjectId("5f85f36d6dfecacc68428a47"),
"game": "Valorant",
"name": "Shroud"
}
{
"_id": ObjectId("5f85f36d6dfecacc68428a49"),
"game": "Starcraft",
"name": "TLO"
}
{
"_id": ObjectId("5f85f36d6dfecacc68428a48"),
"game": "Starcraft",
"name": "Serral"
}
Primary field update
Currently, changing the primary field value is disabled and a NotImplementedError
exception will be raised if you try to do so. It is still possible to mutate the
primary field if the field type is mutable but it might result in unexpected
behaviors.
Workaround to modify the primary key
There is still a workaround to update the primary key of a document:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Resulting document associated to the player
{
"_id": ObjectId("ffffffffffffffffffffffff"),
"game": "Valorant",
"name": "Shroud"
}
Delete¶
You can delete instance by passing them to the AIOEngine.delete method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
The collection is now empty .