Skip to content

Commit 52ff8c2

Browse files
authored
PYTHON-3068 Support 'let' option in BulkWriteOptions (mongodb#874)
1 parent dce5072 commit 52ff8c2

File tree

7 files changed

+1118
-2
lines changed

7 files changed

+1118
-2
lines changed

pymongo/bulk.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from bson.objectid import ObjectId
2323
from bson.raw_bson import RawBSONDocument
2424
from bson.son import SON
25+
from pymongo import common
2526
from pymongo.client_session import _validate_session_write_concern
2627
from pymongo.collation import validate_collation_or_none
2728
from pymongo.common import (
@@ -137,13 +138,16 @@ def _raise_bulk_write_error(full_result):
137138
class _Bulk(object):
138139
"""The private guts of the bulk write API."""
139140

140-
def __init__(self, collection, ordered, bypass_document_validation, comment=None):
141+
def __init__(self, collection, ordered, bypass_document_validation, comment=None, let=None):
141142
"""Initialize a _Bulk instance."""
142143
self.collection = collection.with_options(
143144
codec_options=collection.codec_options._replace(
144145
unicode_decode_error_handler="replace", document_class=dict
145146
)
146147
)
148+
self.let = let
149+
if self.let is not None:
150+
common.validate_is_document_type("let", self.let)
147151
self.comment = comment
148152
self.ordered = ordered
149153
self.ops = []
@@ -314,6 +318,8 @@ def _execute_command(
314318
cmd["writeConcern"] = write_concern.document
315319
if self.bypass_doc_val:
316320
cmd["bypassDocumentValidation"] = True
321+
if self.let is not None and run.op_type in (_DELETE, _UPDATE):
322+
cmd["let"] = self.let
317323
if session:
318324
# Start a new retryable write unless one was already
319325
# started for this command.

pymongo/collection.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ def bulk_write(
423423
bypass_document_validation: bool = False,
424424
session: Optional["ClientSession"] = None,
425425
comment: Optional[Any] = None,
426+
let: Optional[Mapping] = None,
426427
) -> BulkWriteResult:
427428
"""Send a batch of write operations to the server.
428429
@@ -474,6 +475,10 @@ def bulk_write(
474475
:class:`~pymongo.client_session.ClientSession`.
475476
- `comment` (optional): A user-provided comment to attach to this
476477
command.
478+
- `let` (optional): Map of parameter names and values. Values must be
479+
constant or closed expressions that do not reference document
480+
fields. Parameters can then be accessed as variables in an
481+
aggregate expression context (e.g. "$$var").
477482
478483
:Returns:
479484
An instance of :class:`~pymongo.results.BulkWriteResult`.
@@ -485,6 +490,7 @@ def bulk_write(
485490
486491
.. versionchanged:: 4.1
487492
Added ``comment`` parameter.
493+
Added ``let`` parameter.
488494
489495
.. versionchanged:: 3.6
490496
Added ``session`` parameter.
@@ -496,7 +502,7 @@ def bulk_write(
496502
"""
497503
common.validate_list("requests", requests)
498504

499-
blk = _Bulk(self, ordered, bypass_document_validation, comment=comment)
505+
blk = _Bulk(self, ordered, bypass_document_validation, comment=comment, let=let)
500506
for request in requests:
501507
try:
502508
request._add_to_bulk(blk)
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
{
2+
"description": "BulkWrite deleteMany-let",
3+
"schemaVersion": "1.0",
4+
"createEntities": [
5+
{
6+
"client": {
7+
"id": "client0",
8+
"observeEvents": [
9+
"commandStartedEvent"
10+
]
11+
}
12+
},
13+
{
14+
"database": {
15+
"id": "database0",
16+
"client": "client0",
17+
"databaseName": "crud-tests"
18+
}
19+
},
20+
{
21+
"collection": {
22+
"id": "collection0",
23+
"database": "database0",
24+
"collectionName": "coll0"
25+
}
26+
}
27+
],
28+
"initialData": [
29+
{
30+
"collectionName": "coll0",
31+
"databaseName": "crud-tests",
32+
"documents": [
33+
{
34+
"_id": 1
35+
},
36+
{
37+
"_id": 2
38+
}
39+
]
40+
}
41+
],
42+
"tests": [
43+
{
44+
"description": "BulkWrite deleteMany with let option",
45+
"runOnRequirements": [
46+
{
47+
"minServerVersion": "5.0"
48+
}
49+
],
50+
"operations": [
51+
{
52+
"object": "collection0",
53+
"name": "bulkWrite",
54+
"arguments": {
55+
"requests": [
56+
{
57+
"deleteMany": {
58+
"filter": {
59+
"$expr": {
60+
"$eq": [
61+
"$_id",
62+
"$$id"
63+
]
64+
}
65+
}
66+
}
67+
}
68+
],
69+
"let": {
70+
"id": 1
71+
}
72+
}
73+
}
74+
],
75+
"expectEvents": [
76+
{
77+
"client": "client0",
78+
"events": [
79+
{
80+
"commandStartedEvent": {
81+
"command": {
82+
"delete": "coll0",
83+
"deletes": [
84+
{
85+
"q": {
86+
"$expr": {
87+
"$eq": [
88+
"$_id",
89+
"$$id"
90+
]
91+
}
92+
},
93+
"limit": 0
94+
}
95+
],
96+
"let": {
97+
"id": 1
98+
}
99+
}
100+
}
101+
}
102+
]
103+
}
104+
],
105+
"outcome": [
106+
{
107+
"collectionName": "coll0",
108+
"databaseName": "crud-tests",
109+
"documents": [
110+
{
111+
"_id": 2
112+
}
113+
]
114+
}
115+
]
116+
},
117+
{
118+
"description": "Bulk Write deleteMany with let option unsupported (server-side error)",
119+
"runOnRequirements": [
120+
{
121+
"minServerVersion": "3.6.0",
122+
"maxServerVersion": "4.9"
123+
}
124+
],
125+
"operations": [
126+
{
127+
"object": "collection0",
128+
"name": "bulkWrite",
129+
"arguments": {
130+
"requests": [
131+
{
132+
"deleteOne": {
133+
"filter": {
134+
"$expr": {
135+
"$eq": [
136+
"$_id",
137+
"$$id"
138+
]
139+
}
140+
}
141+
}
142+
}
143+
],
144+
"let": {
145+
"id": 1
146+
}
147+
},
148+
"expectError": {
149+
"errorContains": "'delete.let' is an unknown field",
150+
"isClientError": false
151+
}
152+
}
153+
],
154+
"expectEvents": [
155+
{
156+
"client": "client0",
157+
"events": [
158+
{
159+
"commandStartedEvent": {
160+
"command": {
161+
"delete": "coll0",
162+
"deletes": [
163+
{
164+
"q": {
165+
"$expr": {
166+
"$eq": [
167+
"$_id",
168+
"$$id"
169+
]
170+
}
171+
},
172+
"limit": 1
173+
}
174+
],
175+
"let": {
176+
"id": 1
177+
}
178+
}
179+
}
180+
}
181+
]
182+
}
183+
],
184+
"outcome": [
185+
{
186+
"collectionName": "coll0",
187+
"databaseName": "crud-tests",
188+
"documents": [
189+
{
190+
"_id": 1
191+
},
192+
{
193+
"_id": 2
194+
}
195+
]
196+
}
197+
]
198+
}
199+
]
200+
}

0 commit comments

Comments
 (0)