Skip to content
This repository was archived by the owner on Dec 1, 2025. It is now read-only.

PyMongo >= 4.2#53

Closed
jkassemi wants to merge 2 commits intomasterfrom
jk-pymongo-4x-upgrade
Closed

PyMongo >= 4.2#53
jkassemi wants to merge 2 commits intomasterfrom
jk-pymongo-4x-upgrade

Conversation

@jkassemi
Copy link

@jkassemi jkassemi commented Jan 14, 2025

Bumps PyMongo from 3.12.3 to 4.2 and addresses accompanying failures

@jkassemi jkassemi force-pushed the jk-pymongo-4x-upgrade branch from d1a7a21 to 3d54315 Compare January 14, 2025 18:19
@jkassemi jkassemi marked this pull request as draft January 14, 2025 19:31
@jkassemi jkassemi force-pushed the jk-pymongo-4x-upgrade branch from 44a4020 to 3daf679 Compare January 16, 2025 19:23
@jkassemi
Copy link
Author

jkassemi commented Jan 16, 2025

After moving to MongoClient from MongoReplicaSetClient:

FAILED tests/document/test_instance.py::InstanceTest::test_can_save_if_not_included - ValueError: cannot encode native uuid.UUID with UuidRepresentation.UNSPECIFIED. UUIDs can be manually converted to b...
FAILED tests/document/test_instance.py::InstanceTest::test_do_not_save_unchanged_references - AttributeError: type object 'Collection' has no attribute 'update'
FAILED tests/document/test_json_serialisation.py::TestJson::test_json_complex - ValueError: cannot encode native uuid.UUID with UuidRepresentation.UNSPECIFIED. UUIDs can be manually converted to b...
FAILED tests/fields/test_fields.py::FieldTest::test_uuid_field_binary - ValueError: cannot encode native uuid.UUID with UuidRepresentation.UNSPECIFIED. UUIDs can be manually converted to b...
FAILED tests/queryset/test_queryset.py::QuerySetTest::test_json_complex - ValueError: cannot encode native uuid.UUID with UuidRepresentation.UNSPECIFIED. UUIDs can be manually converted to b...
FAILED tests/test_connection.py::ConnectionTest::test_connect - AttributeError: module 'pymongo' has no attribute 'mongo_client'
FAILED tests/test_connection.py::ConnectionTest::test_connect_uri - TypeError: 'Collection' object is not callable. If you meant to call the 'authenticate' method on a 'Database' objec...
FAILED tests/test_connection.py::ConnectionTest::test_register_connection - AttributeError: module 'pymongo' has no attribute 'mongo_client'

PyMongo 3.x encoded native UUIDs into a BSON Binary subtype 3 object. There's a transition under foot to the new subtype 4 object, in which some of the non-python clients that write UUIDs with varying byte orders will be standardized on the python client format.

Callers will need to explicitly pass a encoding options as PYTHON_LEGACY moving forward to ensure compatibility with all clients. PyMongo plans to use the STANDARD uuid representation in a future breaking change.

@jkassemi
Copy link
Author

jkassemi commented Jan 16, 2025

After the PYTHON_LEGACY updates:

FAILED tests/document/test_instance.py::InstanceTest::test_do_not_save_unchanged_references - AttributeError: type object 'Collection' has no attribute 'update'
FAILED tests/test_connection.py::ConnectionTest::test_connect - AttributeError: module 'pymongo' has no attribute 'mongo_client'
FAILED tests/test_connection.py::ConnectionTest::test_connect_uri - TypeError: 'Collection' object is not callable. If you meant to call the 'authenticate' method on a 'Database' ob...
FAILED tests/test_connection.py::ConnectionTest::test_register_connection - AttributeError: module 'pymongo' has no attribute 'mongo_client'

@jkassemi
Copy link
Author

PyMongo 4.x doesn't export mongo_client and database, which results in some failures to import them from the module's init. Importing them directly addresses those failures.

We're now left with the following:

FAILED tests/document/test_instance.py::InstanceTest::test_do_not_save_unchanged_references - AttributeError: type object 'Collection' has no attribute 'update'
FAILED tests/test_connection.py::ConnectionTest::test_connect_uri - TypeError: 'Collection' object is not callable. If you meant to call the 'authenticate' method on a 'Database' ob...

@jkassemi jkassemi force-pushed the jk-pymongo-4x-upgrade branch from cfa0deb to 39a801f Compare January 16, 2025 21:46
@jkassemi
Copy link
Author

jkassemi commented Jan 16, 2025

Collection.update was removed, and we need to use Collection.update_one in its place. This just impacts a test, but once we've got that done:

FAILED tests/test_connection.py::ConnectionTest::test_connect_uri - TypeError: 'Collection' object is not callable. If you meant to call the 'authenticate' method on a 'Database' ob...

https://pymongo.readthedocs.io/en/stable/migrate-to-pymongo4.html#collection-update-is-removed

Copy link
Member

@wojcikstefan wojcikstefan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is getting close!

I'd suggest still moving the most obvious and logically separate changes into their own PRs and merging / deploying them separately. This reduces the risk of each change and increases our ability to quickly identify what caused a potential issue. Slow is smooth and smooth is fast :)

@jkassemi jkassemi force-pushed the jk-pymongo-4x-upgrade branch 3 times, most recently from e73f408 to 8fd3f25 Compare January 22, 2025 20:56
PyMongo `~=4.0` removes `Cursor.count` and `Collection.count` and provides
two new count methods: `Collection.count_documents` and
`Collection.estimated_document_count`.

Both `Cursor.count` and `Collection.count` in PyMongo `~=3.0` use `count` MongoDB
command, which provide potentially inaccurate results when executd without a query
predicate, in a transaction, or on a sharded cluster.

`Collection.count_documents` issues an aggregate query, which is accurate in
all cases, but relatively expensive.

`Collection.estimated_document_count` in PyMongo `>=4.0,<4.2` uses a $collStats
aggregation to estimate the document count for the collection. In PyMongo `>4.2`
it relies on the `count` MongoDB command.

When possible, we now try using the estimated document count for count operations,
but if a limit or skip is defined, or a hint is provided, we'll use the more accurate
count.

This mirrors the behavior of the upstream mongoengine implementation.
@jkassemi jkassemi force-pushed the jk-pymongo-4x-upgrade branch from 8fd3f25 to 27badf2 Compare January 23, 2025 04:38
@jkassemi jkassemi closed this Jan 27, 2025
@wojcikstefan
Copy link
Member

wojcikstefan commented Jan 28, 2025

@jkassemi we should probably update requirements.txt to point to PyMongo v4.2 now. So far, it still points to v3.12.3, which means that's what the CI tests are running with:

pymongo==3.12.3

Is there anything else that was part of this PR and that's still missing from the master branch?

@jkassemi
Copy link
Author

@jkassemi we should probably update requirements.txt to point to PyMongo v4.2 now.

👍 #64

Is there anything else that was part of this PR and that's still missing from the master branch?

Let's get the upper bound <5.0 into setup.py's pymongo requirement - #65

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants