@@ -2258,10 +2258,6 @@ def _aggregate(self, pipeline, cursor_class, first_batch_size, session,
2258
2258
if first_batch_size is not None and not dollar_out :
2259
2259
kwargs ["cursor" ]["batchSize" ] = first_batch_size
2260
2260
2261
- if (sock_info .max_wire_version >= 5 and dollar_out and
2262
- not self .write_concern .is_server_default ):
2263
- cmd ['writeConcern' ] = self .write_concern .document
2264
-
2265
2261
cmd .update (kwargs )
2266
2262
# Apply this Collection's read concern if $out is not in the
2267
2263
# pipeline.
@@ -2271,6 +2267,10 @@ def _aggregate(self, pipeline, cursor_class, first_batch_size, session,
2271
2267
read_concern = self .read_concern
2272
2268
else :
2273
2269
read_concern = None
2270
+ if 'writeConcern' not in cmd and dollar_out :
2271
+ write_concern = self .write_concern
2272
+ else :
2273
+ write_concern = None
2274
2274
2275
2275
# Avoid auto-injecting a session: aggregate() passes a session,
2276
2276
# aggregate_raw_batches() passes none.
@@ -2282,17 +2282,18 @@ def _aggregate(self, pipeline, cursor_class, first_batch_size, session,
2282
2282
self .codec_options ,
2283
2283
parse_write_concern_error = True ,
2284
2284
read_concern = read_concern ,
2285
+ write_concern = write_concern ,
2285
2286
collation = collation ,
2286
2287
session = session ,
2287
2288
client = self .__database .client )
2288
2289
2289
2290
if "cursor" in result :
2290
2291
cursor = result ["cursor" ]
2291
2292
else :
2292
- # Pre-MongoDB 2.6. Fake a cursor.
2293
+ # Pre-MongoDB 2.6 or unacknowledged write . Fake a cursor.
2293
2294
cursor = {
2294
2295
"id" : 0 ,
2295
- "firstBatch" : result [ "result" ] ,
2296
+ "firstBatch" : result . get ( "result" , []) ,
2296
2297
"ns" : self .full_name ,
2297
2298
}
2298
2299
@@ -2586,14 +2587,15 @@ def rename(self, new_name, session=None, **kwargs):
2586
2587
2587
2588
new_name = "%s.%s" % (self .__database .name , new_name )
2588
2589
cmd = SON ([("renameCollection" , self .__full_name ), ("to" , new_name )])
2590
+ cmd .update (kwargs )
2591
+ write_concern = self ._write_concern_for_cmd (cmd )
2592
+
2589
2593
with self ._socket_for_writes () as sock_info :
2590
2594
with self .__database .client ._tmp_session (session ) as s :
2591
- if (sock_info .max_wire_version >= 5 and
2592
- not self .write_concern .is_server_default ):
2593
- cmd ['writeConcern' ] = self .write_concern .document
2594
- cmd .update (kwargs )
2595
2595
return sock_info .command (
2596
- 'admin' , cmd , parse_write_concern_error = True ,
2596
+ 'admin' , cmd ,
2597
+ write_concern = write_concern ,
2598
+ parse_write_concern_error = True ,
2597
2599
session = s , client = self .__database .client )
2598
2600
2599
2601
def distinct (self , key , filter = None , session = None , ** kwargs ):
@@ -2716,20 +2718,20 @@ def map_reduce(self, map, reduce, out, full_response=False, session=None,
2716
2718
inline = 'inline' in cmd ['out' ]
2717
2719
sock_ctx , read_pref = self ._socket_for_primary_reads (session )
2718
2720
with sock_ctx as (sock_info , slave_ok ):
2719
- if (sock_info .max_wire_version >= 5 and
2720
- not self .write_concern .is_server_default and
2721
- not inline ):
2722
- cmd ['writeConcern' ] = self .write_concern .document
2723
- cmd .update (kwargs )
2724
2721
if (sock_info .max_wire_version >= 4 and 'readConcern' not in cmd and
2725
2722
inline ):
2726
2723
read_concern = self .read_concern
2727
2724
else :
2728
2725
read_concern = None
2726
+ if 'writeConcern' not in cmd and not inline :
2727
+ write_concern = self .write_concern
2728
+ else :
2729
+ write_concern = None
2729
2730
2730
2731
response = self ._command (
2731
2732
sock_info , cmd , slave_ok , read_pref ,
2732
2733
read_concern = read_concern ,
2734
+ write_concern = write_concern ,
2733
2735
collation = collation , session = session )
2734
2736
2735
2737
if full_response or not response .get ('result' ):
@@ -2796,6 +2798,13 @@ def inline_map_reduce(self, map, reduce, full_response=False, session=None,
2796
2798
else :
2797
2799
return res .get ("results" )
2798
2800
2801
+ def _write_concern_for_cmd (self , cmd ):
2802
+ raw_wc = cmd .get ('writeConcern' )
2803
+ if raw_wc is not None :
2804
+ return WriteConcern (** raw_wc )
2805
+ else :
2806
+ return self .write_concern
2807
+
2799
2808
def __find_and_modify (self , filter , projection , sort , upsert = None ,
2800
2809
return_document = ReturnDocument .BEFORE ,
2801
2810
array_filters = None , session = None , ** kwargs ):
@@ -2818,11 +2827,7 @@ def __find_and_modify(self, filter, projection, sort, upsert=None,
2818
2827
common .validate_boolean ("upsert" , upsert )
2819
2828
cmd ["upsert" ] = upsert
2820
2829
2821
- write_concern = cmd .get ('writeConcern' )
2822
- if write_concern is not None :
2823
- acknowledged = write_concern .get ("w" ) != 0
2824
- else :
2825
- acknowledged = self .write_concern .acknowledged
2830
+ write_concern = self ._write_concern_for_cmd (cmd )
2826
2831
2827
2832
def _find_and_modify (session , sock_info , retryable_write ):
2828
2833
if array_filters is not None :
@@ -2835,20 +2840,20 @@ def _find_and_modify(session, sock_info, retryable_write):
2835
2840
'arrayFilters is unsupported for unacknowledged '
2836
2841
'writes.' )
2837
2842
cmd ["arrayFilters" ] = array_filters
2838
- if sock_info .max_wire_version >= 4 and 'writeConcern' not in cmd :
2839
- wc_doc = self .write_concern .document
2840
- if wc_doc :
2841
- cmd ['writeConcern' ] = wc_doc
2843
+ if (sock_info .max_wire_version >= 4 and
2844
+ not write_concern .is_server_default ):
2845
+ cmd ['writeConcern' ] = write_concern .document
2842
2846
out = self ._command (sock_info , cmd ,
2843
2847
read_preference = ReadPreference .PRIMARY ,
2848
+ write_concern = write_concern ,
2844
2849
allowable_errors = [_NO_OBJ_ERROR ],
2845
2850
collation = collation , session = session ,
2846
2851
retryable_write = retryable_write )
2847
2852
_check_write_command_response (out )
2848
2853
return out .get ("value" )
2849
2854
2850
2855
return self .__database .client ._retryable_write (
2851
- acknowledged , _find_and_modify , session )
2856
+ write_concern . acknowledged , _find_and_modify , session )
2852
2857
2853
2858
def find_one_and_delete (self , filter ,
2854
2859
projection = None , sort = None , session = None , ** kwargs ):
@@ -3245,17 +3250,12 @@ def find_and_modify(self, query={}, update=None,
3245
3250
cmd = SON ([("findAndModify" , self .__name )])
3246
3251
cmd .update (kwargs )
3247
3252
3248
- write_concern = cmd .get ('writeConcern' )
3249
- if write_concern is not None :
3250
- acknowledged = write_concern .get ("w" ) != 0
3251
- else :
3252
- acknowledged = self .write_concern .acknowledged
3253
+ write_concern = self ._write_concern_for_cmd (cmd )
3253
3254
3254
3255
def _find_and_modify (session , sock_info , retryable_write ):
3255
- if sock_info .max_wire_version >= 4 and 'writeConcern' not in cmd :
3256
- wc_doc = self .write_concern .document
3257
- if wc_doc :
3258
- cmd ['writeConcern' ] = wc_doc
3256
+ if (sock_info .max_wire_version >= 4 and
3257
+ not write_concern .is_server_default ):
3258
+ cmd ['writeConcern' ] = write_concern .document
3259
3259
result = self ._command (
3260
3260
sock_info , cmd , read_preference = ReadPreference .PRIMARY ,
3261
3261
allowable_errors = [_NO_OBJ_ERROR ], collation = collation ,
@@ -3265,7 +3265,7 @@ def _find_and_modify(session, sock_info, retryable_write):
3265
3265
return result
3266
3266
3267
3267
out = self .__database .client ._retryable_write (
3268
- acknowledged , _find_and_modify , None )
3268
+ write_concern . acknowledged , _find_and_modify , None )
3269
3269
3270
3270
if not out ['ok' ]:
3271
3271
if out ["errmsg" ] == _NO_OBJ_ERROR :
0 commit comments