Skip to content

Commit 479e40b

Browse files
authored
Merge pull request #270777 from AbhinavTrips/main
transactional Batch for cosmos DB python SDK update
2 parents 39ddabf + adf9bb5 commit 479e40b

File tree

1 file changed

+138
-9
lines changed

1 file changed

+138
-9
lines changed

articles/cosmos-db/nosql/transactional-batch.md

Lines changed: 138 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
---
2-
title: Transactional batch operations in Azure Cosmos DB using the .NET or Java SDK
3-
description: Learn how to use TransactionalBatch in the Azure Cosmos DB .NET or Java SDK to perform a group of point operations that either succeed or fail.
4-
author: stefArroyo
2+
title: Transactional batch operations in Azure Cosmos DB using the .NET, Java or Python SDK
3+
description: Learn how to use TransactionalBatch in the Azure Cosmos DB .NET, Java SDK or Python SDK to perform a group of point operations that either succeed or fail.
4+
author: stefArroyo
55
ms.author: esarroyo
66
ms.service: cosmos-db
77
ms.subservice: nosql
8-
ms.custom: devx-track-dotnet, devx-track-extended-java
8+
ms.custom: devx-track-dotnet, devx-track-extended-java, devx-track-python
99
ms.topic: conceptual
1010
ms.date: 10/27/2020
1111
---
1212

13-
# Transactional batch operations in Azure Cosmos DB using the .NET or Java SDK
13+
# Transactional batch operations in Azure Cosmos DB
1414
[!INCLUDE[NoSQL](../includes/appliesto-nosql.md)]
1515

16-
Transactional batch describes a group of point operations that need to either succeed or fail together with the same partition key in a container. In the .NET and Java SDKs, the `TransactionalBatch` class is used to define this batch of operations. If all operations succeed in the order they're described within the transactional batch operation, the transaction will be committed. However, if any operation fails, the entire transaction is rolled back.
16+
Transactional batch describes a group of point operations that need to either succeed or fail together with the same partition key in a container. Operations are defined, added to the batch, and the batch is executed. If all operations succeed in the order they're described within the transactional batch operation, the transaction will be committed. However, if any operation fails, the entire transaction is rolled back.
1717

1818
## What's a transaction in Azure Cosmos DB
1919

@@ -138,11 +138,140 @@ if (response.isSuccessStatusCode())
138138
> [!IMPORTANT]
139139
> If there's a failure, the failed operation will have a status code of its corresponding error. All the other operations will have a 424 status code (failed dependency). If the operation fails because it tries to create an item that already exists, a status code of 409 (conflict) is returned. The status code enables one to identify the cause of transaction failure.
140140
141+
### [Python](#tab/python)
142+
143+
Get or create a container instance:
144+
145+
```python
146+
container = database.create_container_if_not_exists(id="batch_container",
147+
partition_key=PartitionKey(path='/road_bikes'))
148+
```
149+
In Python, Transactional Batch operations look very similar to the singular operations apis, and are tuples containing (operation_type_string, args_tuple, batch_operation_kwargs_dictionary). Below are sample items that will be used to demonstrate batch operations functionality:
150+
151+
```python
152+
153+
create_demo_item = {
154+
"id": "68719520766",
155+
"category": "road-bikes",
156+
"name": "Chropen Road Bike"
157+
}
158+
159+
# for demo, assume that this item already exists in the container.
160+
# the item id will be used for read operation in the batch
161+
read_demo_item1 = {
162+
"id": "68719519884",
163+
"category": "road-bikes",
164+
"name": "Tronosuros Tire",
165+
"productId": "68719520766"
166+
}
167+
168+
# for demo, assume that this item already exists in the container.
169+
# the item id will be used for read operation in the batch
170+
read_demo_item2 = {
171+
"id": "68719519886",
172+
"category": "road-bikes",
173+
"name": "Tronosuros Tire",
174+
"productId": "68719520766"
175+
}
176+
177+
# for demo, assume that this item already exists in the container.
178+
# the item id will be used for read operation in the batch
179+
read_demo_item3 = {
180+
"id": "68719519887",
181+
"category": "road-bikes",
182+
"name": "Tronosuros Tire",
183+
"productId": "68719520766"
184+
}
185+
186+
# for demo, we'll upsert the item with id 68719519885
187+
upsert_demo_item = {
188+
"id": "68719519885",
189+
"category": "road-bikes",
190+
"name": "Tronosuros Tire Upserted",
191+
"productId": "68719520768"
192+
}
193+
194+
# for replace demo, we'll replace the read_demo_item2 with this item
195+
replace_demo_item = {
196+
"id": "68719519886",
197+
"category": "road-bikes",
198+
"name": "Tronosuros Tire replaced",
199+
"productId": "68719520769"
200+
}
201+
202+
# for replace with etag match demo, we'll replace the read_demo_item3 with this item
203+
# The use of etags and if-match/if-none-match options allows users to run conditional replace operations
204+
# based on the etag value passed. When using if-match, the request will only succeed if the item's latest etag
205+
# matches the passed in value. For more on optimistic concurrency control, see the link below:
206+
# https://learn.microsoft.com/azure/cosmos-db/nosql/database-transactions-optimistic-concurrency
207+
replace_demo_item_if_match_operation = {
208+
"id": "68719519887",
209+
"category": "road-bikes",
210+
"name": "Tronosuros Tireh",
211+
"wasReplaced": "Replaced based on etag match"
212+
"productId": "68719520769"
213+
}
214+
215+
```
216+
217+
Prepare the operations to be added to the batch:
218+
219+
```python
220+
create_item_operation = ("create", (create_demo_item,), {})
221+
read_item_operation = ("read", ("68719519884",), {})
222+
delete_item_operation = ("delete", ("68719519885",), {})
223+
upsert_item_operation = ("upsert", (upsert_demo_item,), {})
224+
replace_item_operation = ("replace", ("68719519886", replace_demo_item), {})
225+
replace_item_if_match_operation = ("replace",
226+
("68719519887", replace_demo_item_if_match_operation),
227+
{"if_match_etag": container.client_connection.last_response_headers.get("etag")})
228+
```
229+
Add the operations to the batch:
230+
231+
```python
232+
batch_operations = [
233+
create_item_operation,
234+
read_item_operation,
235+
delete_item_operation,
236+
upsert_item_operation,
237+
replace_item_operation,
238+
replace_item_if_match_operation
239+
]
240+
```
241+
242+
Finally, execute the batch:
243+
244+
```python
245+
try:
246+
# Run that list of operations
247+
batch_results = container.execute_item_batch(batch_operations=batch_operations, partition_key="road_bikes")
248+
# Batch results are returned as a list of item operation results - or raise a CosmosBatchOperationError if
249+
# one of the operations failed within your batch request.
250+
print("\nResults for the batch operations: {}\n".format(batch_results))
251+
except exceptions.CosmosBatchOperationError as e:
252+
error_operation_index = e.error_index
253+
error_operation_response = e.operation_responses[error_operation_index]
254+
error_operation = batch_operations[error_operation_index]
255+
print("\nError operation: {}, error operation response: {}\n".format(error_operation, error_operation_response))
256+
# [END handle_batch_error]
257+
```
258+
> **Note for using patch operation and replace_if_match_etag operation in the batch** <br>
259+
The batch operation kwargs dictionary is limited, and only takes a total of three different key values. In the case of wanting to use conditional patching within the batch, the use of filter_predicate key is available for the patch operation, or in case of wanting to use etags with any of the operations, the use of the if_match_etag/if_none_match_etag keys is available as well.<br>
260+
>```python
261+
> batch_operations = [
262+
> ("replace", (item_id, item_body), {"if_match_etag": etag}),
263+
> ("patch", (item_id, operations), {"filter_predicate": filter_predicate, "if_none_match_etag": etag}),
264+
> ]
265+
>```
266+
267+
268+
> [!IMPORTANT]
269+
> If there's a failure, the failed operation will have a status code of its corresponding error. All the other operations will have a 424 status code (failed dependency). If the operation fails because it tries to create an item that already exists, a status code of 409 (conflict) is returned. The status code enables one to identify the cause of transaction failure.
141270
---
142271
143272
## How are transactional batch operations executed
144273
145-
When the `ExecuteAsync` method is called, all operations in the `TransactionalBatch` object are grouped, serialized into a single payload, and sent as a single request to the Azure Cosmos DB service.
274+
When the Transactional Batch is executed, all operations in the Transactional Batch are grouped, serialized into a single payload, and sent as a single request to the Azure Cosmos DB service.
146275
147276
The service receives the request and executes all operations within a transactional scope, and returns a response using the same serialization protocol. This response is either a success, or a failure, and supplies individual operation responses per operation.
148277
@@ -152,8 +281,8 @@ The SDK exposes the response for you to verify the result and, optionally, extra
152281
153282
Currently, there are two known limits:
154283
155-
* The Azure Cosmos DB request size limit constrains the size of the `TransactionalBatch` payload to not exceed 2 MB, and the maximum execution time is 5 seconds.
156-
* There's a current limit of 100 operations per `TransactionalBatch` to ensure the performance is as expected and within SLAs.
284+
* The Azure Cosmos DB request size limit constrains the size of the Transactional Batch payload to not exceed 2 MB, and the maximum execution time is 5 seconds.
285+
* There's a current limit of 100 operations per Transactional Batch to ensure the performance is as expected and within SLAs.
157286
158287
## Next steps
159288

0 commit comments

Comments
 (0)