Skip to content

Commit 9d47f1c

Browse files
committed
PYTHON-691 - Fix UserWarning command issues.
Don't raise UserWarning for helpers and internal calls to commands that do not obey read preference.
1 parent d703ebb commit 9d47f1c

16 files changed

+800
-559
lines changed

gridfs/grid_file.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from pymongo.collection import Collection
3131
from pymongo.cursor import Cursor
3232
from pymongo.errors import DuplicateKeyError
33+
from pymongo.read_preferences import ReadPreference
3334

3435
try:
3536
_SEEK_SET = os.SEEK_SET
@@ -258,7 +259,8 @@ def __flush(self):
258259
db.error()
259260

260261
md5 = db.command(
261-
"filemd5", self._id, root=self._coll.name)["md5"]
262+
"filemd5", self._id, root=self._coll.name,
263+
read_preference=ReadPreference.PRIMARY)["md5"]
262264

263265
self._file["md5"] = md5
264266
self._file["length"] = self._position

pymongo/collection.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from pymongo.errors import InvalidName, OperationFailure
2929
from pymongo.helpers import _check_write_command_response
3030
from pymongo.message import _INSERT, _UPDATE, _DELETE
31+
from pymongo.read_preferences import ReadPreference
3132

3233

3334
try:
@@ -125,9 +126,12 @@ def __create(self, options):
125126
if options:
126127
if "size" in options:
127128
options["size"] = float(options["size"])
128-
self.__database.command("create", self.__name, **options)
129+
self.__database.command("create", self.__name,
130+
read_preference=ReadPreference.PRIMARY,
131+
**options)
129132
else:
130-
self.__database.command("create", self.__name)
133+
self.__database.command("create", self.__name,
134+
read_preference=ReadPreference.PRIMARY)
131135

132136
def __getattr__(self, name):
133137
"""Get a sub-collection of this collection by name.
@@ -1037,7 +1041,9 @@ def create_index(self, key_or_list, cache_for=300, **kwargs):
10371041
index.update(kwargs)
10381042

10391043
try:
1040-
self.__database.command('createIndexes', self.name, indexes=[index])
1044+
self.__database.command('createIndexes', self.name,
1045+
read_preference=ReadPreference.PRIMARY,
1046+
indexes=[index])
10411047
except OperationFailure, exc:
10421048
if exc.code in (59, None):
10431049
index["ns"] = self.__full_name
@@ -1183,7 +1189,9 @@ def drop_index(self, index_or_name):
11831189

11841190
self.__database.connection._purge_index(self.__database.name,
11851191
self.__name, name)
1186-
self.__database.command("dropIndexes", self.__name, index=name,
1192+
self.__database.command("dropIndexes", self.__name,
1193+
read_preference=ReadPreference.PRIMARY,
1194+
index=name,
11871195
allowable_errors=["ns not found"])
11881196

11891197
def reindex(self):
@@ -1195,7 +1203,8 @@ def reindex(self):
11951203
11961204
.. versionadded:: 1.11+
11971205
"""
1198-
return self.__database.command("reIndex", self.__name)
1206+
return self.__database.command("reIndex", self.__name,
1207+
read_preference=ReadPreference.PRIMARY)
11991208

12001209
def index_information(self):
12011210
"""Get information on this collection's indexes.
@@ -1416,9 +1425,10 @@ def rename(self, new_name, **kwargs):
14161425
raise InvalidName("collection names must not contain '$'")
14171426

14181427
new_name = "%s.%s" % (self.__database.name, new_name)
1419-
self.__database.connection.admin.command("renameCollection",
1420-
self.__full_name,
1421-
to=new_name, **kwargs)
1428+
client = self.__database.connection
1429+
client.admin.command("renameCollection", self.__full_name,
1430+
read_preference=ReadPreference.PRIMARY,
1431+
to=new_name, **kwargs)
14221432

14231433
def distinct(self, key):
14241434
"""Get a list of distinct values for `key` among all documents
@@ -1645,6 +1655,7 @@ def find_and_modify(self, query={}, update=None,
16451655

16461656
out = self.__database.command("findAndModify", self.__name,
16471657
allowable_errors=[no_obj_error],
1658+
read_preference=ReadPreference.PRIMARY,
16481659
uuid_subtype=self.uuid_subtype,
16491660
**kwargs)
16501661

pymongo/database.py

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
ConfigurationError,
2727
InvalidName,
2828
OperationFailure)
29-
from pymongo import read_preferences as rp
29+
from pymongo.read_preferences import (modes,
30+
secondary_ok_commands,
31+
ReadPreference)
3032

3133

3234
def _check_name(name):
@@ -282,7 +284,7 @@ def _command(self, command, value=1,
282284

283285
command_name = command.keys()[0].lower()
284286
must_use_master = kwargs.pop('_use_master', False)
285-
if command_name not in rp.secondary_ok_commands:
287+
if command_name not in secondary_ok_commands:
286288
must_use_master = True
287289

288290
# Special-case: mapreduce can go to secondaries only if inline
@@ -323,13 +325,13 @@ def _command(self, command, value=1,
323325
command.update(kwargs)
324326

325327
# Warn if must_use_master will override read_preference.
326-
if (extra_opts['read_preference'] != rp.ReadPreference.PRIMARY and
328+
if (extra_opts['read_preference'] != ReadPreference.PRIMARY and
327329
extra_opts['_must_use_master']):
328330
warnings.warn("%s does not support %s read preference "
329331
"and will be routed to the primary instead." %
330332
(command_name,
331-
rp.modes[extra_opts['read_preference']]),
332-
UserWarning)
333+
modes[extra_opts['read_preference']]),
334+
UserWarning, stacklevel=3)
333335

334336
cursor = self["$cmd"].find(command, **extra_opts).limit(-1)
335337
for doc in cursor:
@@ -466,7 +468,8 @@ def drop_collection(self, name_or_collection):
466468

467469
self.__connection._purge_index(self.__name, name)
468470

469-
self.command("drop", unicode(name), allowable_errors=["ns not found"])
471+
self.command("drop", unicode(name), allowable_errors=["ns not found"],
472+
read_preference=ReadPreference.PRIMARY)
470473

471474
def validate_collection(self, name_or_collection,
472475
scandata=False, full=False):
@@ -504,7 +507,8 @@ def validate_collection(self, name_or_collection,
504507
"%s or Collection" % (basestring.__name__,))
505508

506509
result = self.command("validate", unicode(name),
507-
scandata=scandata, full=full)
510+
scandata=scandata, full=full,
511+
read_preference=ReadPreference.PRIMARY)
508512

509513
valid = True
510514
# Pre 1.9 results
@@ -553,7 +557,8 @@ def profiling_level(self):
553557
554558
.. mongodoc:: profiling
555559
"""
556-
result = self.command("profile", -1)
560+
result = self.command("profile", -1,
561+
read_preference=ReadPreference.PRIMARY)
557562

558563
assert result["was"] >= 0 and result["was"] <= 2
559564
return result["was"]
@@ -593,9 +598,11 @@ def set_profiling_level(self, level, slow_ms=None):
593598
raise TypeError("slow_ms must be an integer")
594599

595600
if slow_ms is not None:
596-
self.command("profile", level, slowms=slow_ms)
601+
self.command("profile", level, slowms=slow_ms,
602+
read_preference=ReadPreference.PRIMARY)
597603
else:
598-
self.command("profile", level)
604+
self.command("profile", level,
605+
read_preference=ReadPreference.PRIMARY)
599606

600607
def profiling_info(self):
601608
"""Returns a list containing current profiling information.
@@ -610,7 +617,8 @@ def error(self):
610617
Return None if the last operation was error-free. Otherwise return the
611618
error that occurred.
612619
"""
613-
error = self.command("getlasterror")
620+
error = self.command("getlasterror",
621+
read_preference=ReadPreference.PRIMARY)
614622
error_msg = error.get("err", "")
615623
if error_msg is None:
616624
return None
@@ -623,7 +631,8 @@ def last_status(self):
623631
624632
Returns a SON object with status information.
625633
"""
626-
return self.command("getlasterror")
634+
return self.command("getlasterror",
635+
read_preference=ReadPreference.PRIMARY)
627636

628637
def previous_error(self):
629638
"""Get the most recent error to have occurred on this database.
@@ -632,7 +641,8 @@ def previous_error(self):
632641
`Database.reset_error_history`. Returns None if no such errors have
633642
occurred.
634643
"""
635-
error = self.command("getpreverror")
644+
error = self.command("getpreverror",
645+
read_preference=ReadPreference.PRIMARY)
636646
if error.get("err", 0) is None:
637647
return None
638648
return error
@@ -643,7 +653,8 @@ def reset_error_history(self):
643653
Calls to `Database.previous_error` will only return errors that have
644654
occurred since the most recent call to this method.
645655
"""
646-
self.command("reseterror")
656+
self.command("reseterror",
657+
read_preference=ReadPreference.PRIMARY)
647658

648659
def __iter__(self):
649660
return self
@@ -697,7 +708,8 @@ def _create_or_update_user(
697708
else:
698709
command_name = "updateUser"
699710

700-
self.command(command_name, name, **opts)
711+
self.command(command_name, name,
712+
read_preference=ReadPreference.PRIMARY, **opts)
701713

702714
def _legacy_add_user(self, name, password, read_only, **kwargs):
703715
"""Uses v1 system to add users, i.e. saving to system.users.
@@ -763,7 +775,8 @@ def add_user(self, name, password=None, read_only=None, **kwargs):
763775
"read_only and roles together")
764776

765777
try:
766-
uinfo = self.command("usersInfo", name)
778+
uinfo = self.command("usersInfo", name,
779+
read_preference=ReadPreference.PRIMARY)
767780
except OperationFailure, exc:
768781
# MongoDB >= 2.5.3 requires the use of commands to manage
769782
# users. "No such command" error didn't return an error
@@ -793,6 +806,7 @@ def remove_user(self, name):
793806

794807
try:
795808
self.command("dropUser", name,
809+
read_preference=ReadPreference.PRIMARY,
796810
writeConcern=self._get_wc_override())
797811
except OperationFailure, exc:
798812
# See comment in add_user try / except above.
@@ -930,7 +944,9 @@ def eval(self, code, *args):
930944
if not isinstance(code, Code):
931945
code = Code(code)
932946

933-
result = self.command("$eval", code, args=args)
947+
result = self.command("$eval", code,
948+
read_preference=ReadPreference.PRIMARY,
949+
args=args)
934950
return result.get("retval", None)
935951

936952
def __call__(self, *args, **kwargs):

pymongo/mongo_client.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@
6161
InvalidURI,
6262
OperationFailure)
6363
from pymongo.member import Member
64+
from pymongo.read_preferences import ReadPreference
65+
66+
6467
EMPTY = b("")
6568

6669

@@ -1337,13 +1340,15 @@ def kill_cursors(self, cursor_ids):
13371340
def server_info(self):
13381341
"""Get information about the MongoDB server we're connected to.
13391342
"""
1340-
return self.admin.command("buildinfo")
1343+
return self.admin.command("buildinfo",
1344+
read_preference=ReadPreference.PRIMARY)
13411345

13421346
def database_names(self):
13431347
"""Get a list of the names of all databases on the connected server.
13441348
"""
13451349
return [db["name"] for db in
1346-
self.admin.command("listDatabases")["databases"]]
1350+
self.admin.command("listDatabases",
1351+
read_preference=ReadPreference.PRIMARY)["databases"]]
13471352

13481353
def drop_database(self, name_or_database):
13491354
"""Drop a database.
@@ -1365,7 +1370,8 @@ def drop_database(self, name_or_database):
13651370
"%s or Database" % (basestring.__name__,))
13661371

13671372
self._purge_index(name)
1368-
self[name].command("dropDatabase")
1373+
self[name].command("dropDatabase",
1374+
read_preference=ReadPreference.PRIMARY)
13691375

13701376
def copy_database(self, from_name, to_name,
13711377
from_host=None, username=None, password=None):
@@ -1413,12 +1419,15 @@ def copy_database(self, from_name, to_name,
14131419

14141420
if username is not None:
14151421
nonce = self.admin.command("copydbgetnonce",
1416-
fromhost=from_host)["nonce"]
1422+
read_preference=ReadPreference.PRIMARY,
1423+
fromhost=from_host)["nonce"]
14171424
command["username"] = username
14181425
command["nonce"] = nonce
14191426
command["key"] = auth._auth_key(nonce, username, password)
14201427

1421-
return self.admin.command("copydb", **command)
1428+
return self.admin.command("copydb",
1429+
read_preference=ReadPreference.PRIMARY,
1430+
**command)
14221431
finally:
14231432
self.end_request()
14241433

@@ -1467,7 +1476,8 @@ def fsync(self, **kwargs):
14671476
14681477
.. versionadded:: 2.0
14691478
"""
1470-
self.admin.command("fsync", **kwargs)
1479+
self.admin.command("fsync",
1480+
read_preference=ReadPreference.PRIMARY, **kwargs)
14711481

14721482
def unlock(self):
14731483
"""Unlock a previously locked server.

pymongo/mongo_replica_set_client.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
DuplicateKeyError,
6060
OperationFailure,
6161
InvalidOperation)
62+
from pymongo.read_preferences import ReadPreference
6263
from pymongo.thread_util import DummyLock
6364

6465
EMPTY = b("")
@@ -1832,13 +1833,15 @@ def close_cursor(self, cursor_id, _conn_id):
18321833
def server_info(self):
18331834
"""Get information about the MongoDB primary we're connected to.
18341835
"""
1835-
return self.admin.command("buildinfo")
1836+
return self.admin.command("buildinfo",
1837+
read_preference=ReadPreference.PRIMARY)
18361838

18371839
def database_names(self):
18381840
"""Get a list of the names of all databases on the connected server.
18391841
"""
18401842
return [db["name"] for db in
1841-
self.admin.command("listDatabases")["databases"]]
1843+
self.admin.command("listDatabases",
1844+
read_preference=ReadPreference.PRIMARY)["databases"]]
18421845

18431846
def drop_database(self, name_or_database):
18441847
"""Drop a database.
@@ -1860,7 +1863,8 @@ def drop_database(self, name_or_database):
18601863
"%s or Database" % (basestring.__name__,))
18611864

18621865
self._purge_index(name)
1863-
self[name].command("dropDatabase")
1866+
self[name].command("dropDatabase",
1867+
read_preference=ReadPreference.PRIMARY)
18641868

18651869
def copy_database(self, from_name, to_name,
18661870
from_host=None, username=None, password=None):
@@ -1906,12 +1910,15 @@ def copy_database(self, from_name, to_name,
19061910

19071911
if username is not None:
19081912
nonce = self.admin.command("copydbgetnonce",
1909-
fromhost=from_host)["nonce"]
1913+
read_preference=ReadPreference.PRIMARY,
1914+
fromhost=from_host)["nonce"]
19101915
command["username"] = username
19111916
command["nonce"] = nonce
19121917
command["key"] = auth._auth_key(nonce, username, password)
19131918

1914-
return self.admin.command("copydb", **command)
1919+
return self.admin.command("copydb",
1920+
read_preference=ReadPreference.PRIMARY,
1921+
**command)
19151922
finally:
19161923
self.end_request()
19171924

0 commit comments

Comments
 (0)