1PyMongo 3 Migration Guide 2========================= 3 4.. contents:: 5 6.. testsetup:: 7 8 from pymongo import MongoClient, ReadPreference 9 client = MongoClient() 10 collection = client.my_database.my_collection 11 12PyMongo 3 is a partial rewrite bringing a large number of improvements. It 13also brings a number of backward breaking changes. This guide provides a 14roadmap for migrating an existing application from PyMongo 2.x to 3.x or 15writing libraries that will work with both PyMongo 2.x and 3.x. 16 17PyMongo 2.9 18----------- 19 20The first step in any successful migration involves upgrading to, or 21requiring, at least PyMongo 2.9. If your project has a 22requirements.txt file, add the line "pymongo >= 2.9, < 3.0" until you have 23completely migrated to PyMongo 3. Most of the key new 24methods and options from PyMongo 3.0 are backported in PyMongo 2.9 making 25migration much easier. 26 27Enable Deprecation Warnings 28--------------------------- 29 30Starting with PyMongo 2.9, :exc:`DeprecationWarning` is raised by most methods 31removed in PyMongo 3.0. Make sure you enable runtime warnings to see 32where deprecated functions and methods are being used in your application:: 33 34 python -Wd <your application> 35 36Warnings can also be changed to errors:: 37 38 python -Wd -Werror <your application> 39 40.. note:: Not all deprecated features raise :exc:`DeprecationWarning` when 41 used. For example, the :meth:`~pymongo.collection.Collection.find` options 42 renamed in PyMongo 3.0 do not raise :exc:`DeprecationWarning` when used in 43 PyMongo 2.x. See also `Removed features with no migration path`_. 44 45CRUD API 46-------- 47 48Changes to find() and find_one() 49................................ 50 51"spec" renamed "filter" 52~~~~~~~~~~~~~~~~~~~~~~~ 53 54The `spec` option has been renamed to `filter`. Code like this:: 55 56 >>> cursor = collection.find(spec={"a": 1}) 57 58can be changed to this with PyMongo 2.9 or later: 59 60.. doctest:: 61 62 >>> cursor = collection.find(filter={"a": 1}) 63 64or this with any version of PyMongo: 65 66.. doctest:: 67 68 >>> cursor = collection.find({"a": 1}) 69 70"fields" renamed "projection" 71~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 72 73The `fields` option has been renamed to `projection`. Code like this:: 74 75 >>> cursor = collection.find({"a": 1}, fields={"_id": False}) 76 77can be changed to this with PyMongo 2.9 or later: 78 79.. doctest:: 80 81 >>> cursor = collection.find({"a": 1}, projection={"_id": False}) 82 83or this with any version of PyMongo: 84 85.. doctest:: 86 87 >>> cursor = collection.find({"a": 1}, {"_id": False}) 88 89"partial" renamed "allow_partial_results" 90~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 91 92The `partial` option has been renamed to `allow_partial_results`. Code like 93this:: 94 95 >>> cursor = collection.find({"a": 1}, partial=True) 96 97can be changed to this with PyMongo 2.9 or later: 98 99.. doctest:: 100 101 >>> cursor = collection.find({"a": 1}, allow_partial_results=True) 102 103"timeout" replaced by "no_cursor_timeout" 104~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 105 106The `timeout` option has been replaced by `no_cursor_timeout`. Code like this:: 107 108 >>> cursor = collection.find({"a": 1}, timeout=False) 109 110can be changed to this with PyMongo 2.9 or later: 111 112.. doctest:: 113 114 >>> cursor = collection.find({"a": 1}, no_cursor_timeout=True) 115 116"network_timeout" is removed 117~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 118 119The `network_timeout` option has been removed. This option was always the 120wrong solution for timing out long running queries and should never be used 121in production. Starting with **MongoDB 2.6** you can use the $maxTimeMS query 122modifier. Code like this:: 123 124 # Set a 5 second select() timeout. 125 >>> cursor = collection.find({"a": 1}, network_timeout=5) 126 127can be changed to this with PyMongo 2.9 or later: 128 129.. doctest:: 130 131 # Set a 5 second (5000 millisecond) server side query timeout. 132 >>> cursor = collection.find({"a": 1}, modifiers={"$maxTimeMS": 5000}) 133 134or with PyMongo 3.5 or later: 135 136 >>> cursor = collection.find({"a": 1}, max_time_ms=5000) 137 138or with any version of PyMongo: 139 140.. doctest:: 141 142 >>> cursor = collection.find({"$query": {"a": 1}, "$maxTimeMS": 5000}) 143 144.. seealso:: `$maxTimeMS 145 <http://docs.mongodb.org/manual/reference/operator/meta/maxTimeMS/>`_ 146 147Tailable cursors 148~~~~~~~~~~~~~~~~ 149 150The `tailable` and `await_data` options have been replaced by `cursor_type`. 151Code like this:: 152 153 >>> cursor = collection.find({"a": 1}, tailable=True) 154 >>> cursor = collection.find({"a": 1}, tailable=True, await_data=True) 155 156can be changed to this with PyMongo 2.9 or later: 157 158.. doctest:: 159 160 >>> from pymongo import CursorType 161 >>> cursor = collection.find({"a": 1}, cursor_type=CursorType.TAILABLE) 162 >>> cursor = collection.find({"a": 1}, cursor_type=CursorType.TAILABLE_AWAIT) 163 164Other removed options 165~~~~~~~~~~~~~~~~~~~~~ 166 167The `slave_okay`, `read_preference`, `tag_sets`, 168and `secondary_acceptable_latency_ms` options have been removed. See the `Read 169Preferences`_ section for solutions. 170 171The aggregate method always returns a cursor 172............................................ 173 174PyMongo 2.6 added an option to return an iterable cursor from 175:meth:`~pymongo.collection.Collection.aggregate`. In PyMongo 3 176:meth:`~pymongo.collection.Collection.aggregate` always returns a cursor. Use 177the `cursor` option for consistent behavior with PyMongo 2.9 and later: 178 179.. doctest:: 180 181 >>> for result in collection.aggregate([], cursor={}): 182 ... pass 183 184Read Preferences 185---------------- 186 187The "slave_okay" option is removed 188.................................. 189 190The `slave_okay` option is removed from PyMongo's API. The 191secondaryPreferred read preference provides the same behavior. 192Code like this:: 193 194 >>> client = MongoClient(slave_okay=True) 195 196can be changed to this with PyMongo 2.9 or newer: 197 198.. doctest:: 199 200 >>> client = MongoClient(readPreference="secondaryPreferred") 201 202The "read_preference" attribute is immutable 203............................................ 204 205Code like this:: 206 207 >>> from pymongo import ReadPreference 208 >>> db = client.my_database 209 >>> db.read_preference = ReadPreference.SECONDARY 210 211can be changed to this with PyMongo 2.9 or later: 212 213.. doctest:: 214 215 >>> db = client.get_database("my_database", 216 ... read_preference=ReadPreference.SECONDARY) 217 218Code like this:: 219 220 >>> cursor = collection.find({"a": 1}, 221 ... read_preference=ReadPreference.SECONDARY) 222 223can be changed to this with PyMongo 2.9 or later: 224 225.. doctest:: 226 227 >>> coll2 = collection.with_options(read_preference=ReadPreference.SECONDARY) 228 >>> cursor = coll2.find({"a": 1}) 229 230.. seealso:: :meth:`~pymongo.database.Database.get_collection` 231 232The "tag_sets" option and attribute are removed 233............................................... 234 235The `tag_sets` MongoClient option is removed. The `read_preference` 236option can be used instead. Code like this:: 237 238 >>> client = MongoClient( 239 ... read_preference=ReadPreference.SECONDARY, 240 ... tag_sets=[{"dc": "ny"}, {"dc": "sf"}]) 241 242can be changed to this with PyMongo 2.9 or later: 243 244.. doctest:: 245 246 >>> from pymongo.read_preferences import Secondary 247 >>> client = MongoClient(read_preference=Secondary([{"dc": "ny"}])) 248 249To change the tags sets for a Database or Collection, code like this:: 250 251 >>> db = client.my_database 252 >>> db.read_preference = ReadPreference.SECONDARY 253 >>> db.tag_sets = [{"dc": "ny"}] 254 255can be changed to this with PyMongo 2.9 or later: 256 257.. doctest:: 258 259 >>> db = client.get_database("my_database", 260 ... read_preference=Secondary([{"dc": "ny"}])) 261 262Code like this:: 263 264 >>> cursor = collection.find( 265 ... {"a": 1}, 266 ... read_preference=ReadPreference.SECONDARY, 267 ... tag_sets=[{"dc": "ny"}]) 268 269can be changed to this with PyMongo 2.9 or later: 270 271.. doctest:: 272 273 >>> from pymongo.read_preferences import Secondary 274 >>> coll2 = collection.with_options( 275 ... read_preference=Secondary([{"dc": "ny"}])) 276 >>> cursor = coll2.find({"a": 1}) 277 278.. seealso:: :meth:`~pymongo.database.Database.get_collection` 279 280The "secondary_acceptable_latency_ms" option and attribute are removed 281...................................................................... 282 283PyMongo 2.x supports `secondary_acceptable_latency_ms` as an option to methods 284throughout the driver, but mongos only supports a global latency option. 285PyMongo 3.x has changed to match the behavior of mongos, allowing migration 286from a single server, to a replica set, to a sharded cluster without a 287surprising change in server selection behavior. A new option, 288`localThresholdMS`, is available through MongoClient and should be used in 289place of `secondaryAcceptableLatencyMS`. Code like this:: 290 291 >>> client = MongoClient(readPreference="nearest", 292 ... secondaryAcceptableLatencyMS=100) 293 294can be changed to this with PyMongo 2.9 or later: 295 296.. doctest:: 297 298 >>> client = MongoClient(readPreference="nearest", 299 ... localThresholdMS=100) 300 301Write Concern 302------------- 303 304The "safe" option is removed 305............................ 306 307In PyMongo 3 the `safe` option is removed from the entire API. 308:class:`~pymongo.mongo_client.MongoClient` has always defaulted to acknowledged 309write operations and continues to do so in PyMongo 3. 310 311The "write_concern" attribute is immutable 312.......................................... 313 314The `write_concern` attribute is immutable in PyMongo 3. Code like this:: 315 316 >>> client = MongoClient() 317 >>> client.write_concern = {"w": "majority"} 318 319can be changed to this with any version of PyMongo: 320 321.. doctest:: 322 323 >>> client = MongoClient(w="majority") 324 325Code like this:: 326 327 >>> db = client.my_database 328 >>> db.write_concern = {"w": "majority"} 329 330can be changed to this with PyMongo 2.9 or later: 331 332.. doctest:: 333 334 >>> from pymongo import WriteConcern 335 >>> db = client.get_database("my_database", 336 ... write_concern=WriteConcern(w="majority")) 337 338The new CRUD API write methods do not accept write concern options. Code like 339this:: 340 341 >>> oid = collection.insert({"a": 2}, w="majority") 342 343can be changed to this with PyMongo 2.9 or later: 344 345.. doctest:: 346 347 >>> from pymongo import WriteConcern 348 >>> coll2 = collection.with_options( 349 ... write_concern=WriteConcern(w="majority")) 350 >>> oid = coll2.insert({"a": 2}) 351 352.. seealso:: :meth:`~pymongo.database.Database.get_collection` 353 354Codec Options 355------------- 356 357The "document_class" attribute is removed 358......................................... 359 360Code like this:: 361 362 >>> from bson.son import SON 363 >>> client = MongoClient() 364 >>> client.document_class = SON 365 366can be replaced by this in any version of PyMongo: 367 368.. doctest:: 369 370 >>> from bson.son import SON 371 >>> client = MongoClient(document_class=SON) 372 373or to change the `document_class` for a :class:`~pymongo.database.Database` 374with PyMongo 2.9 or later: 375 376.. doctest:: 377 378 >>> from bson.codec_options import CodecOptions 379 >>> from bson.son import SON 380 >>> db = client.get_database("my_database", CodecOptions(SON)) 381 382.. seealso:: :meth:`~pymongo.database.Database.get_collection` and 383 :meth:`~pymongo.collection.Collection.with_options` 384 385The "uuid_subtype" option and attribute are removed 386................................................... 387 388Code like this:: 389 390 >>> from bson.binary import JAVA_LEGACY 391 >>> db = client.my_database 392 >>> db.uuid_subtype = JAVA_LEGACY 393 394can be replaced by this with PyMongo 2.9 or later: 395 396.. doctest:: 397 398 >>> from bson.binary import JAVA_LEGACY 399 >>> from bson.codec_options import CodecOptions 400 >>> db = client.get_database("my_database", 401 ... CodecOptions(uuid_representation=JAVA_LEGACY)) 402 403.. seealso:: :meth:`~pymongo.database.Database.get_collection` and 404 :meth:`~pymongo.collection.Collection.with_options` 405 406MongoClient 407----------- 408 409MongoClient connects asynchronously 410................................... 411 412In PyMongo 3, the :class:`~pymongo.mongo_client.MongoClient` constructor no 413longer blocks while connecting to the server or servers, and it no longer 414raises :exc:`~pymongo.errors.ConnectionFailure` if they are unavailable, nor 415:exc:`~pymongo.errors.ConfigurationError` if the user’s credentials are wrong. 416Instead, the constructor returns immediately and launches the connection 417process on background threads. The `connect` option is added to control whether 418these threads are started immediately, or when the client is first used. 419 420For consistent behavior in PyMongo 2.x and PyMongo 3.x, code like this:: 421 422 >>> from pymongo.errors import ConnectionFailure 423 >>> try: 424 ... client = MongoClient() 425 ... except ConnectionFailure: 426 ... print("Server not available") 427 >>> 428 429can be changed to this with PyMongo 2.9 or later: 430 431.. doctest:: 432 433 >>> from pymongo.errors import ConnectionFailure 434 >>> client = MongoClient(connect=False) 435 >>> try: 436 ... result = client.admin.command("ping") 437 ... except ConnectionFailure: 438 ... print("Server not available") 439 >>> 440 441Any operation can be used to determine if the server is available. We choose 442the "ping" command here because it is cheap and does not require auth, so 443it is a simple way to check whether the server is available. 444 445The max_pool_size parameter is removed 446...................................... 447 448PyMongo 3 replaced the max_pool_size parameter with support for the MongoDB URI 449`maxPoolSize` option. Code like this:: 450 451 >>> client = MongoClient(max_pool_size=10) 452 453can be replaced by this with PyMongo 2.9 or later: 454 455.. doctest:: 456 457 >>> client = MongoClient(maxPoolSize=10) 458 >>> client = MongoClient("mongodb://localhost:27017/?maxPoolSize=10") 459 460The "disconnect" method is removed 461.................................. 462 463Code like this:: 464 465 >>> client.disconnect() 466 467can be replaced by this with PyMongo 2.9 or later: 468 469.. doctest:: 470 471 >>> client.close() 472 473The host and port attributes are removed 474........................................ 475 476Code like this:: 477 478 >>> host = client.host 479 >>> port = client.port 480 481can be replaced by this with PyMongo 2.9 or later: 482 483.. doctest:: 484 485 >>> address = client.address 486 >>> host, port = address or (None, None) 487 488BSON 489---- 490 491"as_class", "tz_aware", and "uuid_subtype" are removed 492...................................................... 493 494The `as_class`, `tz_aware`, and `uuid_subtype` parameters have been 495removed from the functions provided in :mod:`bson`. Furthermore, the 496:func:`~bson.encode` and :func:`~bson.decode` functions have been added 497as more performant alternatives to the :meth:`bson.BSON.encode` and 498:meth:`bson.BSON.decode` methods. Code like this:: 499 500 >>> from bson import BSON 501 >>> from bson.son import SON 502 >>> encoded = BSON.encode({"a": 1}, as_class=SON) 503 504can be replaced by this in PyMongo 2.9 or later: 505 506.. doctest:: 507 508 >>> from bson import encode 509 >>> from bson.codec_options import CodecOptions 510 >>> from bson.son import SON 511 >>> encoded = encode({"a": 1}, codec_options=CodecOptions(SON)) 512 513Removed features with no migration path 514--------------------------------------- 515 516MasterSlaveConnection is removed 517................................ 518 519Master slave deployments are no longer supported by MongoDB. Starting with 520MongoDB 3.0 a replica set can have up to 50 members and that limit is likely 521to be removed in later releases. We recommend migrating to replica sets 522instead. 523 524Requests are removed 525.................... 526 527The client methods `start_request`, `in_request`, and `end_request` are 528removed. Requests were designed to make read-your-writes consistency more 529likely with the w=0 write concern. Additionally, a thread in a request used the 530same member for all secondary reads in a replica set. To ensure 531read-your-writes consistency in PyMongo 3.0, do not override the default write 532concern with w=0, and do not override the default read preference of PRIMARY. 533 534The "compile_re" option is removed 535.................................. 536 537In PyMongo 3 regular expressions are never compiled to Python match objects. 538 539The "use_greenlets" option is removed 540..................................... 541 542The `use_greenlets` option was meant to allow use of PyMongo with Gevent 543without the use of gevent.monkey.patch_threads(). This option caused a lot 544of confusion and made it difficult to support alternative asyncio libraries 545like Eventlet. Users of Gevent should use gevent.monkey.patch_all() instead. 546 547.. seealso:: :doc:`examples/gevent` 548