2025, Nov 10 19:00
Resolve '_QUERY_OPTIONS' ImportError after upgrading to PyMongo 4.9+: Beanie compatibility and AsyncMongoClient migration
Hit ImportError '_QUERY_OPTIONS' after switching from motor to PyMongo's AsyncMongoClient? Learn the cause in PyMongo 4.9+, Beanie fixes, and version pinning.
When migrating from motor to PyMongo's AsyncMongoClient, an unexpected import failure can surface in projects that also use Beanie or similar ODMs. A typical symptom is that a plain import of Beanie’s Document raises an ImportError right after upgrading PyMongo. This happens on modern Python too; for instance, the scenario below was reproduced on Python 3.11.9 with a dependency set that included beanie==1.29.0 and pymongo==4.13.2.
Reproducing the issue
The failure appears during import time. A minimal example looks like this:
from pymongo.asyncio import AsyncMongoClient as AsyncClient
from beanie import Document as DocBase
Running this code results in:
ImportError: cannot import name '_QUERY_OPTIONS' from 'pymongo.cursor'
What’s going on under the hood
The root cause is a breaking change introduced in PyMongo releases starting from 4.9. In those versions, the _QUERY_OPTIONS attribute was removed from pymongo.cursor. Any library that still references this internal attribute will fail at import time until it is updated to accommodate the change. This affects older releases of libraries in the MongoDB Python ecosystem that depend on PyMongo internals, including some combinations of beanie and mongoengine. The behavior matches the public discussion around Beanie’s compatibility, as captured in the related pull request: https://github.com/BeanieODM/beanie/pull/1027.
How to fix it
There are two paths forward, and which one you choose depends on your stack constraints. The first option is to update the dependent library to a version that is compatible with PyMongo ≥ 4.9. The second option is to pin PyMongo below 4.9 to avoid the breaking change. If you opt for pinning, adjust your installation or requirements accordingly:
pymongo<4.9
beanie==1.29.0
With a compatible set of versions in place, the same imports will work as expected:
from pymongo.asyncio import AsyncMongoClient as AsyncClient
from beanie import Document as DocBase
If you are already planning a broader refactor, another viable direction is to streamline around PyMongo alone. One team chose to drop Beanie and rely on AsyncMongoClient, noting that PyMongo provides full async support.
Why this matters
Import-time breakages are costly because they block application startup and CI pipelines before you even reach runtime logic. Here, the incompatibility hinges on a removed internal attribute in PyMongo and a downstream library expecting it to exist. The fix is not in your application code; it lives in dependency alignment. Ensuring that Beanie or any other ODM is compatible with the chosen PyMongo release is essential, especially when migrating from motor to AsyncMongoClient.
Conclusion
If you encounter ImportError: cannot import name '_QUERY_OPTIONS' from 'pymongo.cursor' after upgrading, you are most likely hitting the PyMongo ≥ 4.9 change. Resolve it by updating the dependent library to a compatible release or by pinning PyMongo to a version below 4.9. For teams consolidating technology choices, moving fully to PyMongo’s AsyncMongoClient is also an option, and it provides full async support. The key takeaway is to align your ODM and driver versions so they agree on the internal APIs they rely on.
The article is based on a question from StackOverflow by Masterstack8080 and an answer by Uchenna Adubasim.