Announcing Motor 1.2 Release Candidate, With MongoDB 3.6 Support
MongoDB 3.6 was released December 5. Today I’ve uploaded a release candidate for version 1.2 of Motor, the async Python driver for MongoDB. This will be a big release so I hope you try the release candidate and tell me if it works for you or if you find bugs.
Install the release candidate with pip:
python -m pip install motor==1.2rc0
Compatibility Changes
- MongoDB: drop 2.4, add 3.6
- Python: drop 2.6, continue to support 2.7 and 3.3+
- Tornado: drop 3, continue to support Tornado 4.5+
- aiohttp: support 2.0 and later, drop older version
See the Compatibility Matrix for the relationships among Motor, Python, Tornado, and MongoDB versions.
MongoDB 3.6 Features
Change Streams
There’s a new method MotorCollection.watch to acquire a Change Stream on a collection:
async for change in collection.watch():
print(change)
I’ve written you a little sample app that watches a collection for changes and posts each notification over a websocket using the Tornado webserver:
Causal Consistency
There’s a new Session API to support causal consistency, meaning you can read your writes and perform monotonic reads, even reading from secondaries in a replica set or a sharded cluster. Create a session with MotorClient.start_session and use it for a sequence of related operations:
collection = client.db.collection
with (await client.start_session()) as s:
doc = {'_id': ObjectId(), 'x': 1}
await collection.insert_one(doc, session=s)
secondary = collection.with_options(
read_preference=ReadPreference.SECONDARY)
# Sessions are causally consistent by default, we can read the doc
# we just inserted, even reading from a secondary.
async for doc in secondary.find(session=s):
print(doc)
Array Filters
You can now update subdocuments in arrays within documents, and use “array filters” to choose which subdocuments to change. Pass the array_filters
argument to
MotorCollection.update_one,
MotorCollection.update_many,
MotorCollection.find_one_and_update,
or MotorCollection.bulk_write.
For example if your document looks like this:
{
_id: 1,
points: [
{x: 0, y: 0},
{x: 1, y: 0},
{x: 2, y: 0}
]
}
You can update all subdocuments where x is greater than zero:
await collection.update_one(
{'_id': 1},
{'$set': {'points.$[i].y': 5}},
array_filters=[{'i.x': {'$gt': 0}}])
“mongodb+srv://” URIs
This new URI scheme is convenient for short, maintainable URIs that represent large clusters, especially in Atlas. See PyMongo’s MongoClient for details.
Retryable Writes
Now, with a MongoDB 3.6 replica set or sharded cluster, Motor will safely retry any write that’s interrupted by a network glitch or a primary failover, without any risk of a double write. Just add retryWrites
to the URI:
mongodb://host1,host2,host3/?replicaSet=rs&retryWrites=true
See PyMongo’s MongoClient for details about retryable writes.
Thanks to everyone who contributed to this version:
- A. Jesse Jiryu Davis
- Bernie Hackett
- Jakub Wilk
- Karol Horowski
Peace,
A. Jesse Jiryu Davis