{"id":155,"library":"motor","title":"Motor (Async MongoDB)","description":"DEPRECATED as of May 14, 2025. Motor was the official async Python driver for MongoDB. Superseded by the native AsyncMongoClient in pymongo >= 4.13 (GA). EOL: May 14, 2026. Critical bug fixes only until May 14, 2027. No new features. Current version: 3.7.1. Requires PyMongo 4.9+. For new projects use pymongo's AsyncMongoClient instead.","status":"deprecated","version":"3.7.1","language":"python","source_language":"en","source_url":"https://github.com/mongodb/motor","tags":["motor","mongodb","async","asyncio","python","deprecated"],"install":[{"cmd":"pip install pymongo","lang":"bash","label":"Python (use this — native AsyncMongoClient)"},{"cmd":"pip install motor","lang":"bash","label":"Python (deprecated — EOL May 2026)"}],"dependencies":[{"reason":"Motor wraps pymongo. Requires pymongo >= 4.9. Motor < 3.6 is incompatible with pymongo >= 4.9.","package":"pymongo","optional":false}],"imports":[{"note":"Motor is deprecated. Use AsyncMongoClient from pymongo >= 4.13 for new projects. API is nearly identical — same await patterns, same collection methods.","wrong":"import motor.motor_asyncio\nclient = motor.motor_asyncio.AsyncIOMotorClient('mongodb+srv://...')","symbol":"AsyncMongoClient (recommended — pymongo native)","correct":"from pymongo import AsyncMongoClient\nimport asyncio\n\nasync def main():\n    client = AsyncMongoClient('mongodb+srv://user:pass@cluster.mongodb.net/')\n    db = client['mydb']\n    result = await db['users'].insert_one({'name': 'Alice'})\n    print(result.inserted_id)\n    await client.close()\n\nasyncio.run(main())"},{"note":"Import is motor.motor_asyncio.AsyncIOMotorClient — not motor.MongoClient or motor.AsyncIOMotorClient directly. The motor_asyncio submodule is required.","wrong":"import motor\nclient = motor.MongoClient(...)  # wrong — must use motor.motor_asyncio","symbol":"AsyncIOMotorClient (motor — existing code)","correct":"import motor.motor_asyncio\nimport asyncio\n\nasync def main():\n    client = motor.motor_asyncio.AsyncIOMotorClient(\n        'mongodb+srv://user:pass@cluster.mongodb.net/'\n    )\n    db = client['mydb']\n    result = await db['users'].insert_one({'name': 'Alice'})\n    print(result.inserted_id)\n\nasyncio.run(main())"}],"quickstart":{"code":"# New projects: use pymongo's native async instead of motor\n# pip install 'pymongo[srv]'\nfrom pymongo import AsyncMongoClient\nimport asyncio\n\nasync def main():\n    client = AsyncMongoClient('mongodb+srv://user:pass@cluster.mongodb.net/')\n    db = client['mydb']\n    col = db['users']\n\n    # All same methods as sync pymongo but with await\n    await col.insert_one({'name': 'Alice', 'age': 30})\n    doc = await col.find_one({'name': 'Alice'})\n    print(doc)\n    await col.update_one({'name': 'Alice'}, {'$set': {'age': 31}})\n    count = await col.count_documents({})\n    print(count)\n    await client.close()\n\nasyncio.run(main())","lang":"python","description":"Async MongoDB using pymongo's native AsyncMongoClient (replaces motor)."},"warnings":[{"fix":"Replace motor.motor_asyncio.AsyncIOMotorClient with pymongo.AsyncMongoClient. API is nearly identical.","message":"Motor deprecated May 14, 2025. EOL May 14, 2026. No new features. Bug fixes only. Migrate to pymongo AsyncMongoClient.","severity":"breaking","affected_versions":"all"},{"fix":"Upgrade to Motor >= 3.6 if staying on motor. Or migrate to pymongo AsyncMongoClient.","message":"Motor < 3.6 is incompatible with PyMongo >= 4.9. Version mismatch causes ImportError or unexpected failures.","severity":"breaking","affected_versions":"motor < 3.6 with pymongo >= 4.9"},{"fix":"from motor.motor_asyncio import AsyncIOMotorClient — not from motor import AsyncIOMotorClient","message":"Import path is motor.motor_asyncio.AsyncIOMotorClient — not motor.AsyncIOMotorClient. LLMs frequently drop the motor_asyncio submodule.","severity":"gotcha","affected_versions":"all"},{"fix":"Migrate to pymongo AsyncMongoClient for true async I/O performance.","message":"Motor does NOT use true async I/O — it uses a thread pool under the hood. In high-concurrency scenarios this can cause performance degradation. pymongo's AsyncMongoClient uses true asyncio.","severity":"gotcha","affected_versions":"all"},{"fix":"async for doc in collection.find({}): print(doc)","message":"Motor cursor iteration requires 'async for' not 'for'. Sync iteration over MotorCursor silently returns zero results instead of raising an error.","severity":"gotcha","affected_versions":"all"},{"fix":"Use Python 3.10+ for latest motor versions.","message":"Python 3.8 dropped in motor 3.7. Python 3.9 dropped in motor 3.8. Check compatibility matrix before upgrading.","severity":"gotcha","affected_versions":">= 3.7"},{"fix":"Verify the MongoDB connection string is correctly formatted and accessible. Ensure your environment has proper network access to a DNS server that can resolve SRV records for your MongoDB host. Check for typos in the hostname or issues with firewalls/proxy settings.","message":"PyMongo's AsyncMongoClient failed to resolve SRV record DNS. This `DNS query name does not exist` error often indicates an incorrect MongoDB connection string (especially `mongodb+srv://` URIs) or a network issue preventing DNS resolution for the specified MongoDB host.","severity":"breaking","affected_versions":"pymongo >= 4.0"},{"fix":"Verify the MongoDB Atlas connection string is correct and accessible. Ensure the network environment allows DNS resolution for SRV records (e.g., firewall rules, VPN configuration). Test DNS resolution manually for the SRV record (e.g., `dig SRV _mongodb._tcp.yourcluster.mongodb.net`).","message":"Connecting to MongoDB Atlas via SRV record (mongodb+srv://) fails with `pymongo.errors.ConfigurationError: The DNS query name does not exist`. This indicates an issue with the MongoDB connection URI or the network's ability to resolve SRV DNS records for the specified hostname.","severity":"breaking","affected_versions":"pymongo >= 4.0"}],"env_vars":null,"last_verified":"2026-05-12T09:06:08.815Z","next_check":"2026-05-14T00:00:00.000Z","problems":[{"fix":"Upgrade `motor` to version 3.6.0 or higher, which is compatible with `PyMongo >= 4.9`. Alternatively, if you must use an older `motor` (<3.6), pin your `pymongo` version to `<4.9` (e.g., `pymongo==4.8.0`).","cause":"This error occurs due to an incompatibility between the installed `motor` version and the `pymongo` version, where `motor` is trying to import an internal `pymongo` symbol that has been removed or renamed in newer `pymongo` releases.","error":"ImportError: cannot import name '_QUERY_OPTIONS' from 'pymongo.cursor'"},{"fix":"Verify that your MongoDB server is running and accessible from the application's environment, check the connection string for correctness (including host, port, authentication), and ensure network access rules (e.g., firewalls, security groups, MongoDB Atlas IP whitelist) allow connections. You can also increase `serverSelectionTimeoutMS` in the client constructor if the network is slow.","cause":"This error indicates that the Motor client could not connect to the MongoDB server within the specified timeout period, often due to network issues, incorrect connection string, or the MongoDB server not running or being inaccessible.","error":"pymongo.errors.ServerSelectionTimeoutError"},{"fix":"Before returning MongoDB documents as JSON, convert the `ObjectId` fields (and other BSON types like `datetime`) to strings. This can be done manually or by using `bson.json_util.dumps` for comprehensive serialization of MongoDB types.","cause":"MongoDB documents contain BSON types like `ObjectId` that are not natively recognized by Python's standard `json` library, leading to a `TypeError` when attempting to serialize a document directly to JSON for API responses.","error":"TypeError: Object of type ObjectId is not JSON serializable"},{"fix":"Explicitly compare the `MotorDatabase` instance with `None` if you intend to check if it's been initialized (e.g., `if database is not None:`).","cause":"In Motor 3.0 and later, directly evaluating a `MotorDatabase` instance in a boolean context (e.g., `if database:`) raises this error, as the boolean conversion behavior was removed.","error":"NotImplementedError: __bool__"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":11.2,"disk_size":"26.3M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":11.2,"disk_size":"79.7M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.21,"mem_mb":11.2,"disk_size":"28M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.22,"mem_mb":11.2,"disk_size":"148M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.46,"mem_mb":13.1,"disk_size":"29.7M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.45,"mem_mb":13.1,"disk_size":"87.7M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.37,"mem_mb":13.1,"disk_size":"32M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.36,"mem_mb":13.1,"disk_size":"157M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.6,"mem_mb":13.1,"disk_size":"21.3M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.6,"mem_mb":13.1,"disk_size":"78.6M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.57,"mem_mb":13.1,"disk_size":"25M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.57,"mem_mb":13.1,"disk_size":"149M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.63,"mem_mb":13.5,"disk_size":"20.9M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.59,"mem_mb":13.5,"disk_size":"75.1M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.55,"mem_mb":13.5,"disk_size":"25M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.56,"mem_mb":13.5,"disk_size":"149M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.26,"mem_mb":11,"disk_size":"25.7M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.26,"mem_mb":11,"disk_size":"78.7M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":11,"disk_size":"27M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.22,"mem_mb":11,"disk_size":"147M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}