From 8eeff8efc85b97ac1fbbbb765b8d60844d9d4528 Mon Sep 17 00:00:00 2001 From: Yash Bhutoria Date: Thu, 21 Oct 2021 21:14:38 +0530 Subject: [PATCH] Added support for Async Generators in TableClient.submit_transaction method (#21119) * added support for async iterables in submit_transcation method * the warning is a known issue in pylint https://github.com/PyCQA/pylint/issues/3507 * fixed formatting issues * Code tweaks + tests * Fixed grammar * Improved readability * Fix for Py27 Co-authored-by: antisch --- sdk/tables/azure-data-tables/CHANGELOG.md | 6 +- .../azure/data/tables/_table_batch.py | 21 +- .../azure/data/tables/_table_client.py | 36 ++- .../data/tables/aio/_table_batch_async.py | 13 +- .../data/tables/aio/_table_client_async.py | 39 ++- ..._batch_async.test_async_batch_inserts.yaml | 272 ++++++++++++++++++ ...cosmos_async.test_async_batch_inserts.yaml | 252 ++++++++++++++++ .../tests/test_table_batch_async.py | 26 ++ .../tests/test_table_batch_cosmos_async.py | 26 ++ 9 files changed, 653 insertions(+), 38 deletions(-) create mode 100644 sdk/tables/azure-data-tables/tests/recordings/test_table_batch_async.test_async_batch_inserts.yaml create mode 100644 sdk/tables/azure-data-tables/tests/recordings/test_table_batch_cosmos_async.test_async_batch_inserts.yaml diff --git a/sdk/tables/azure-data-tables/CHANGELOG.md b/sdk/tables/azure-data-tables/CHANGELOG.md index a10e7f5d0c82..651b474b61c1 100644 --- a/sdk/tables/azure-data-tables/CHANGELOG.md +++ b/sdk/tables/azure-data-tables/CHANGELOG.md @@ -1,12 +1,16 @@ # Release History -## 12.1.1 (2021-09-08) +## 12.1.1 (Unreleased) ### Bugs Fixed - Resolved bug where strings couldn't be used instead of enum value for entity Update Mode (#20247). - Resolved bug where single quote characters in Partition and Row keys were not escaped correctly (#20301). +### Features Added + +- Added support for async iterators in `aio.TableClient.submit_transaction (#21083, thank you yashbhutoria). + ### Other Changes - Bumped dependency on `msrest` to `>=0.6.21` diff --git a/sdk/tables/azure-data-tables/azure/data/tables/_table_batch.py b/sdk/tables/azure-data-tables/azure/data/tables/_table_batch.py index f9aec1cfe4b5..741795d33a7a 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/_table_batch.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/_table_batch.py @@ -10,13 +10,14 @@ Dict, Mapping, Optional, - List + List, + Tuple ) from azure.core import MatchConditions from ._common_conversion import _transform_patch_to_cosmos_post -from ._models import UpdateMode +from ._models import UpdateMode, TransactionOperation from ._serialize import _get_match_headers, _add_entity_properties, _prepare_key from ._entity import TableEntity @@ -26,8 +27,10 @@ from ._generated import models, AzureTable from ._generated._configuration import AzureTableConfiguration -EntityType = Union[TableEntity, Mapping[str, Any]] +EntityType = Union[TableEntity, Mapping[str, Any]] +OperationType = Union[TransactionOperation, str] +TransactionOperationType = Union[Tuple[OperationType, EntityType], Tuple[OperationType, EntityType, Mapping[str, Any]]] class TableBatchOperations(object): @@ -91,6 +94,18 @@ def _verify_partition_key( elif entity["PartitionKey"] != self._partition_key: raise ValueError("Partition Keys must all be the same") + def add_operation(self, operation): + # type: (TransactionOperationType) -> None + """Add a single operation to a batch.""" + try: + operation_type, entity, kwargs = operation # type: ignore + except ValueError: + operation_type, entity, kwargs = operation[0], operation[1], {} # type: ignore + try: + getattr(self, operation_type.lower())(entity, **kwargs) + except AttributeError: + raise ValueError("Unrecognized operation: {}".format(operation)) + def create( self, entity, # type: EntityType diff --git a/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py b/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py index 74370e179a95..7d41eed044cd 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py @@ -5,7 +5,7 @@ # -------------------------------------------------------------------------- import functools -from typing import Optional, Any, TYPE_CHECKING, Union, List, Tuple, Dict, Mapping, Iterable, overload, cast +from typing import Optional, Any, TYPE_CHECKING, Union, List, Dict, Mapping, Iterable, overload, cast try: from urllib.parse import urlparse, unquote except ImportError: @@ -34,19 +34,14 @@ from ._base_client import parse_connection_str, TablesBaseClient from ._serialize import serialize_iso, _parameter_filter_substitution from ._deserialize import deserialize_iso, _return_headers_and_deserialized -from ._table_batch import TableBatchOperations +from ._table_batch import TableBatchOperations, EntityType, TransactionOperationType from ._models import ( TableEntityPropertiesPaged, UpdateMode, TableAccessPolicy, - TransactionOperation, TableItem ) -EntityType = Union[TableEntity, Mapping[str, Any]] -OperationType = Union[TransactionOperation, str] -TransactionOperationType = Union[Tuple[OperationType, EntityType], Tuple[OperationType, EntityType, Mapping[str, Any]]] - if TYPE_CHECKING: from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential @@ -691,10 +686,14 @@ def submit_transaction( If any one of these operations fails, the entire transaction will be rejected. - :param operations: The list of operations to commit in a transaction. This should be a list of + :param operations: The list of operations to commit in a transaction. This should be an iterable of tuples containing an operation name, the entity on which to operate, and optionally, a dict of additional - kwargs for that operation. - :type operations: Iterable[Tuple[str, EntityType]] + kwargs for that operation. For example:: + + - ('upsert', {'PartitionKey': 'A', 'RowKey': 'B'}) + - ('upsert', {'PartitionKey': 'A', 'RowKey': 'B'}, {'mode': UpdateMode.REPLACE}) + + :type operations: Iterable[Tuple[str, TableEntity, Mapping[str, Any]]] :return: A list of mappings with response metadata for each operation in the transaction. :rtype: List[Mapping[str, Any]] :raises: :class:`~azure.data.tables.TableTransactionError` @@ -717,13 +716,12 @@ def submit_transaction( is_cosmos_endpoint=self._cosmos_endpoint, **kwargs ) - for operation in operations: - try: - operation_kwargs = operation[2] # type: ignore - except IndexError: - operation_kwargs = {} - try: - getattr(batched_requests, operation[0].lower())(operation[1], **operation_kwargs) - except AttributeError: - raise ValueError("Unrecognized operation: {}".format(operation[0])) + try: + for operation in operations: + batched_requests.add_operation(operation) + except TypeError: + raise TypeError( + "The value of 'operations' must be an iterator " + "of Tuples. Please check documentation for correct Tuple format." + ) return self._batch_send(*batched_requests.requests, **kwargs) # type: ignore diff --git a/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_batch_async.py b/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_batch_async.py index 4e4627bf0a6f..a50f25c0e394 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_batch_async.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_batch_async.py @@ -11,7 +11,7 @@ from .._common_conversion import _transform_patch_to_cosmos_post from .._models import UpdateMode from .._entity import TableEntity -from .._table_batch import EntityType +from .._table_batch import EntityType, TransactionOperationType from .._serialize import ( _prepare_key, _get_match_headers, @@ -68,6 +68,17 @@ def _verify_partition_key( elif entity["PartitionKey"] != self._partition_key: raise ValueError("Partition Keys must all be the same") + def add_operation(self, operation: TransactionOperationType) -> None: + """Add a single operation to a batch.""" + try: + operation_type, entity, kwargs = operation # type: ignore + except ValueError: + operation_type, entity, kwargs = *operation, {} # type: ignore + try: + getattr(self, operation_type.lower())(entity, **kwargs) + except AttributeError: + raise ValueError("Unrecognized operation: {}".format(operation)) + def create( self, entity: EntityType, diff --git a/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py b/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py index 7cb8637a3de2..0f8a5831656b 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py @@ -4,7 +4,7 @@ # license information. # -------------------------------------------------------------------------- import functools -from typing import List, Union, Any, Optional, Mapping, Iterable, Dict, overload, cast, TYPE_CHECKING +from typing import AsyncIterable, List, Union, Any, Optional, Mapping, Iterable, Dict, overload, cast, TYPE_CHECKING try: from urllib.parse import urlparse, unquote except ImportError: @@ -664,17 +664,24 @@ async def upsert_entity( @distributed_trace_async async def submit_transaction( self, - operations: Iterable[TransactionOperationType], + operations: Union[ + Iterable[TransactionOperationType], AsyncIterable[TransactionOperationType] + ], **kwargs ) -> List[Mapping[str, Any]]: """Commit a list of operations as a single transaction. If any one of these operations fails, the entire transaction will be rejected. - :param operations: The list of operations to commit in a transaction. This should be a list of - tuples containing an operation name, the entity on which to operate, and optionally, a dict of additional - kwargs for that operation. - :type operations: Iterable[Tuple[str, EntityType]] + :param operations: The list of operations to commit in a transaction. This should be an iterable + (or async iterable) of tuples containing an operation name, the entity on which to operate, + and optionally, a dict of additional kwargs for that operation. For example:: + + - ('upsert', {'PartitionKey': 'A', 'RowKey': 'B'}) + - ('upsert', {'PartitionKey': 'A', 'RowKey': 'B'}, {'mode': UpdateMode.REPLACE}) + + :type operations: + Union[Iterable[Tuple[str, Entity, Mapping[str, Any]]],AsyncIterable[Tuple[str, Entity, Mapping[str, Any]]]] :return: A list of mappings with response metadata for each operation in the transaction. :rtype: List[Mapping[str, Any]] :raises ~azure.data.tables.TableTransactionError: @@ -697,13 +704,17 @@ async def submit_transaction( is_cosmos_endpoint=self._cosmos_endpoint, **kwargs ) - for operation in operations: - try: - operation_kwargs = operation[2] # type: ignore - except IndexError: - operation_kwargs = {} + try: + for operation in operations: # type: ignore + batched_requests.add_operation(operation) + except TypeError: try: - getattr(batched_requests, operation[0].lower())(operation[1], **operation_kwargs) - except AttributeError: - raise ValueError("Unrecognized operation: {}".format(operation)) + async for operation in operations: # type: ignore + batched_requests.add_operation(operation) + except TypeError: + raise TypeError( + "The value of 'operations' must be an iterator or async iterator " + "of Tuples. Please check documentation for correct Tuple format." + ) + return await self._batch_send(*batched_requests.requests, **kwargs) diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_batch_async.test_async_batch_inserts.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_batch_async.test_async_batch_inserts.yaml new file mode 100644 index 000000000000..2b512eba4c26 --- /dev/null +++ b/sdk/tables/azure-data-tables/tests/recordings/test_table_batch_async.test_async_batch_inserts.yaml @@ -0,0 +1,272 @@ +interactions: +- request: + body: '{"TableName": "uttablecb451339"}' + headers: + Accept: + - application/json;odata=minimalmetadata + Content-Length: + - '32' + Content-Type: + - application/json;odata=nometadata + DataServiceVersion: + - '3.0' + Date: + - Fri, 08 Oct 2021 18:56:51 GMT + User-Agent: + - azsdk-python-data-tables/12.1.1 Python/3.7.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Fri, 08 Oct 2021 18:56:51 GMT + x-ms-version: + - '2019-02-02' + method: POST + uri: https://fake_table_account.table.core.windows.net/Tables + response: + body: + string: '{"odata.metadata":"https://fake_table_account.table.core.windows.net/$metadata#Tables/@Element","TableName":"uttablecb451339"}' + headers: + cache-control: no-cache + content-type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + date: Fri, 08 Oct 2021 18:56:51 GMT + location: https://fake_table_account.table.core.windows.net/Tables('uttablecb451339') + server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + transfer-encoding: chunked + x-content-type-options: nosniff + x-ms-version: '2019-02-02' + status: + code: 201 + message: Created + url: https://pytestremote.table.core.windows.net/Tables +- request: + body: "--batch_d48048fb-c6db-468a-805a-2e864a6486e5\r\nContent-Type: multipart/mixed; + boundary=changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7\r\n\r\n--changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 0\r\n\r\nPATCH + https://pytestremote.table.core.windows.net/uttablecb451339(PartitionKey='async_inserts',RowKey='0') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nx-ms-date: + Fri, 08 Oct 2021 18:56:52 GMT\r\nDate: Fri, 08 Oct 2021 18:56:52 GMT\r\n\r\n{\"PartitionKey\": + \"async_inserts\", \"PartitionKey@odata.type\": \"Edm.String\", \"RowKey\": + \"0\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 1\r\n\r\nPATCH + https://pytestremote.table.core.windows.net/uttablecb451339(PartitionKey='async_inserts',RowKey='1') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nx-ms-date: + Fri, 08 Oct 2021 18:56:52 GMT\r\nDate: Fri, 08 Oct 2021 18:56:52 GMT\r\n\r\n{\"PartitionKey\": + \"async_inserts\", \"PartitionKey@odata.type\": \"Edm.String\", \"RowKey\": + \"1\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 2\r\n\r\nPATCH + https://pytestremote.table.core.windows.net/uttablecb451339(PartitionKey='async_inserts',RowKey='2') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nx-ms-date: + Fri, 08 Oct 2021 18:56:52 GMT\r\nDate: Fri, 08 Oct 2021 18:56:52 GMT\r\n\r\n{\"PartitionKey\": + \"async_inserts\", \"PartitionKey@odata.type\": \"Edm.String\", \"RowKey\": + \"2\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 3\r\n\r\nPATCH + https://pytestremote.table.core.windows.net/uttablecb451339(PartitionKey='async_inserts',RowKey='3') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nx-ms-date: + Fri, 08 Oct 2021 18:56:52 GMT\r\nDate: Fri, 08 Oct 2021 18:56:52 GMT\r\n\r\n{\"PartitionKey\": + \"async_inserts\", \"PartitionKey@odata.type\": \"Edm.String\", \"RowKey\": + \"3\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 4\r\n\r\nPATCH + https://pytestremote.table.core.windows.net/uttablecb451339(PartitionKey='async_inserts',RowKey='4') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nx-ms-date: + Fri, 08 Oct 2021 18:56:52 GMT\r\nDate: Fri, 08 Oct 2021 18:56:52 GMT\r\n\r\n{\"PartitionKey\": + \"async_inserts\", \"PartitionKey@odata.type\": \"Edm.String\", \"RowKey\": + \"4\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 5\r\n\r\nPATCH + https://pytestremote.table.core.windows.net/uttablecb451339(PartitionKey='async_inserts',RowKey='5') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nx-ms-date: + Fri, 08 Oct 2021 18:56:52 GMT\r\nDate: Fri, 08 Oct 2021 18:56:52 GMT\r\n\r\n{\"PartitionKey\": + \"async_inserts\", \"PartitionKey@odata.type\": \"Edm.String\", \"RowKey\": + \"5\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 6\r\n\r\nPATCH + https://pytestremote.table.core.windows.net/uttablecb451339(PartitionKey='async_inserts',RowKey='6') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nx-ms-date: + Fri, 08 Oct 2021 18:56:52 GMT\r\nDate: Fri, 08 Oct 2021 18:56:52 GMT\r\n\r\n{\"PartitionKey\": + \"async_inserts\", \"PartitionKey@odata.type\": \"Edm.String\", \"RowKey\": + \"6\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 7\r\n\r\nPATCH + https://pytestremote.table.core.windows.net/uttablecb451339(PartitionKey='async_inserts',RowKey='7') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nx-ms-date: + Fri, 08 Oct 2021 18:56:52 GMT\r\nDate: Fri, 08 Oct 2021 18:56:52 GMT\r\n\r\n{\"PartitionKey\": + \"async_inserts\", \"PartitionKey@odata.type\": \"Edm.String\", \"RowKey\": + \"7\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 8\r\n\r\nPATCH + https://pytestremote.table.core.windows.net/uttablecb451339(PartitionKey='async_inserts',RowKey='8') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nx-ms-date: + Fri, 08 Oct 2021 18:56:52 GMT\r\nDate: Fri, 08 Oct 2021 18:56:52 GMT\r\n\r\n{\"PartitionKey\": + \"async_inserts\", \"PartitionKey@odata.type\": \"Edm.String\", \"RowKey\": + \"8\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 9\r\n\r\nPATCH + https://pytestremote.table.core.windows.net/uttablecb451339(PartitionKey='async_inserts',RowKey='9') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nx-ms-date: + Fri, 08 Oct 2021 18:56:52 GMT\r\nDate: Fri, 08 Oct 2021 18:56:52 GMT\r\n\r\n{\"PartitionKey\": + \"async_inserts\", \"PartitionKey@odata.type\": \"Edm.String\", \"RowKey\": + \"9\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_a6adc80e-f301-4abc-b710-1dd92a2dcdd7--\r\n\r\n--batch_d48048fb-c6db-468a-805a-2e864a6486e5--\r\n" + headers: + Accept: + - application/json + Content-Length: + - '6118' + Content-Type: + - multipart/mixed; boundary=batch_d48048fb-c6db-468a-805a-2e864a6486e5 + DataServiceVersion: + - '3.0' + Date: + - Fri, 08 Oct 2021 18:56:52 GMT + MaxDataServiceVersion: + - 3.0;NetFx + User-Agent: + - azsdk-python-data-tables/12.1.1 Python/3.7.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Fri, 08 Oct 2021 18:56:52 GMT + x-ms-version: + - '2019-02-02' + method: POST + uri: https://fake_table_account.table.core.windows.net/$batch + response: + body: + string: "--batchresponse_0ef921de-4c6e-4050-8e79-ec6bbe9b0843\r\nContent-Type: + multipart/mixed; boundary=changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b\r\n\r\n--changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 + No Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 1.0;\r\nETag: W/\"datetime'2021-10-08T18%3A56%3A52.0795449Z'\"\r\n\r\n\r\n--changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 + No Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 1.0;\r\nETag: W/\"datetime'2021-10-08T18%3A56%3A52.0795449Z'\"\r\n\r\n\r\n--changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 + No Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 1.0;\r\nETag: W/\"datetime'2021-10-08T18%3A56%3A52.0795449Z'\"\r\n\r\n\r\n--changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 + No Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 1.0;\r\nETag: W/\"datetime'2021-10-08T18%3A56%3A52.0795449Z'\"\r\n\r\n\r\n--changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 + No Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 1.0;\r\nETag: W/\"datetime'2021-10-08T18%3A56%3A52.0795449Z'\"\r\n\r\n\r\n--changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 + No Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 1.0;\r\nETag: W/\"datetime'2021-10-08T18%3A56%3A52.0805457Z'\"\r\n\r\n\r\n--changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 + No Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 1.0;\r\nETag: W/\"datetime'2021-10-08T18%3A56%3A52.0805457Z'\"\r\n\r\n\r\n--changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 + No Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 1.0;\r\nETag: W/\"datetime'2021-10-08T18%3A56%3A52.0805457Z'\"\r\n\r\n\r\n--changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 + No Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 1.0;\r\nETag: W/\"datetime'2021-10-08T18%3A56%3A52.0805457Z'\"\r\n\r\n\r\n--changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 + No Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 1.0;\r\nETag: W/\"datetime'2021-10-08T18%3A56%3A52.0805457Z'\"\r\n\r\n\r\n--changesetresponse_808d1535-a83f-498f-8fd8-5834043c7e3b--\r\n--batchresponse_0ef921de-4c6e-4050-8e79-ec6bbe9b0843--\r\n" + headers: + cache-control: no-cache + content-type: multipart/mixed; boundary=batchresponse_0ef921de-4c6e-4050-8e79-ec6bbe9b0843 + date: Fri, 08 Oct 2021 18:56:51 GMT + server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + transfer-encoding: chunked + x-content-type-options: nosniff + x-ms-version: '2019-02-02' + status: + code: 202 + message: Accepted + url: https://pytestremote.table.core.windows.net/$batch +- request: + body: null + headers: + Accept: + - application/json;odata=minimalmetadata + DataServiceVersion: + - '3.0' + Date: + - Fri, 08 Oct 2021 18:56:52 GMT + User-Agent: + - azsdk-python-data-tables/12.1.1 Python/3.7.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Fri, 08 Oct 2021 18:56:52 GMT + x-ms-version: + - '2019-02-02' + method: GET + uri: https://fake_table_account.table.core.windows.net/uttablecb451339()?$filter=PartitionKey%20eq%20'async_inserts' + response: + body: + string: '{"odata.metadata":"https://fake_table_account.table.core.windows.net/$metadata#uttablecb451339","value":[{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A52.0795449Z''\"","PartitionKey":"async_inserts","RowKey":"0","Timestamp":"2021-10-08T18:56:52.0795449Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A52.0795449Z''\"","PartitionKey":"async_inserts","RowKey":"1","Timestamp":"2021-10-08T18:56:52.0795449Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A52.0795449Z''\"","PartitionKey":"async_inserts","RowKey":"2","Timestamp":"2021-10-08T18:56:52.0795449Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A52.0795449Z''\"","PartitionKey":"async_inserts","RowKey":"3","Timestamp":"2021-10-08T18:56:52.0795449Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A52.0795449Z''\"","PartitionKey":"async_inserts","RowKey":"4","Timestamp":"2021-10-08T18:56:52.0795449Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A52.0805457Z''\"","PartitionKey":"async_inserts","RowKey":"5","Timestamp":"2021-10-08T18:56:52.0805457Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A52.0805457Z''\"","PartitionKey":"async_inserts","RowKey":"6","Timestamp":"2021-10-08T18:56:52.0805457Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A52.0805457Z''\"","PartitionKey":"async_inserts","RowKey":"7","Timestamp":"2021-10-08T18:56:52.0805457Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A52.0805457Z''\"","PartitionKey":"async_inserts","RowKey":"8","Timestamp":"2021-10-08T18:56:52.0805457Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A52.0805457Z''\"","PartitionKey":"async_inserts","RowKey":"9","Timestamp":"2021-10-08T18:56:52.0805457Z"}]}' + headers: + cache-control: no-cache + content-type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + date: Fri, 08 Oct 2021 18:56:51 GMT + server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + transfer-encoding: chunked + x-content-type-options: nosniff + x-ms-version: '2019-02-02' + status: + code: 200 + message: OK + url: https://pytestremote.table.core.windows.net/uttablecb451339()?$filter=PartitionKey%20eq%20'async_inserts' +- request: + body: null + headers: + Accept: + - application/json;odata=minimalmetadata + DataServiceVersion: + - '3.0' + Date: + - Fri, 08 Oct 2021 18:56:52 GMT + User-Agent: + - azsdk-python-data-tables/12.1.1 Python/3.7.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Fri, 08 Oct 2021 18:56:52 GMT + x-ms-version: + - '2019-02-02' + method: GET + uri: https://fake_table_account.table.core.windows.net/Tables + response: + body: + string: '{"odata.metadata":"https://fake_table_account.table.core.windows.net/$metadata#Tables","value":[{"TableName":"uttablecb451339"}]}' + headers: + cache-control: no-cache + content-type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + date: Fri, 08 Oct 2021 18:56:51 GMT + server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + transfer-encoding: chunked + x-content-type-options: nosniff + x-ms-version: '2019-02-02' + status: + code: 200 + message: OK + url: https://pytestremote.table.core.windows.net/Tables +- request: + body: null + headers: + Accept: + - application/json + Date: + - Fri, 08 Oct 2021 18:56:52 GMT + User-Agent: + - azsdk-python-data-tables/12.1.1 Python/3.7.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Fri, 08 Oct 2021 18:56:52 GMT + x-ms-version: + - '2019-02-02' + method: DELETE + uri: https://fake_table_account.table.core.windows.net/Tables('uttablecb451339') + response: + body: + string: '' + headers: + cache-control: no-cache + content-length: '0' + date: Fri, 08 Oct 2021 18:56:52 GMT + server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + x-content-type-options: nosniff + x-ms-version: '2019-02-02' + status: + code: 204 + message: No Content + url: https://pytestremote.table.core.windows.net/Tables('uttablecb451339') +version: 1 diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_batch_cosmos_async.test_async_batch_inserts.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_batch_cosmos_async.test_async_batch_inserts.yaml new file mode 100644 index 000000000000..66263609dafc --- /dev/null +++ b/sdk/tables/azure-data-tables/tests/recordings/test_table_batch_cosmos_async.test_async_batch_inserts.yaml @@ -0,0 +1,252 @@ +interactions: +- request: + body: '{"TableName": "uttable5ffa162c"}' + headers: + Accept: + - application/json;odata=minimalmetadata + Content-Length: + - '32' + Content-Type: + - application/json;odata=nometadata + DataServiceVersion: + - '3.0' + Date: + - Fri, 08 Oct 2021 18:56:52 GMT + User-Agent: + - azsdk-python-data-tables/12.1.1 Python/3.7.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Fri, 08 Oct 2021 18:56:52 GMT + x-ms-version: + - '2019-02-02' + method: POST + uri: https://fake_cosmos_account.table.cosmos.azure.com/Tables + response: + body: + string: '{"TableName":"uttable5ffa162c","odata.metadata":"https://fake_cosmos_account.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + content-type: application/json;odata=minimalmetadata + date: Fri, 08 Oct 2021 18:56:53 GMT + etag: W/"datetime'2021-10-08T18%3A56%3A53.3285895Z'" + location: https://fake_cosmos_account.table.cosmos.azure.com/Tables('uttable5ffa162c') + transfer-encoding: chunked + status: + code: 201 + message: Ok + url: https://pytables3.table.cosmos.azure.com/Tables +- request: + body: "--batch_d4e6ff69-6b3e-4f7f-b872-3e0a5aa70054\r\nContent-Type: multipart/mixed; + boundary=changeset_dc382a3e-6ffd-492d-8317-878ef05160a8\r\n\r\n--changeset_dc382a3e-6ffd-492d-8317-878ef05160a8\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 0\r\n\r\nPOST + https://pytables3.table.cosmos.azure.com/uttable5ffa162c(PartitionKey='async_inserts',RowKey='0') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nX-HTTP-Method: + MERGE\r\nx-ms-date: Fri, 08 Oct 2021 18:56:53 GMT\r\nDate: Fri, 08 Oct 2021 + 18:56:53 GMT\r\n\r\n{\"PartitionKey\": \"async_inserts\", \"PartitionKey@odata.type\": + \"Edm.String\", \"RowKey\": \"0\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_dc382a3e-6ffd-492d-8317-878ef05160a8\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 1\r\n\r\nPOST + https://pytables3.table.cosmos.azure.com/uttable5ffa162c(PartitionKey='async_inserts',RowKey='1') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nX-HTTP-Method: + MERGE\r\nx-ms-date: Fri, 08 Oct 2021 18:56:53 GMT\r\nDate: Fri, 08 Oct 2021 + 18:56:53 GMT\r\n\r\n{\"PartitionKey\": \"async_inserts\", \"PartitionKey@odata.type\": + \"Edm.String\", \"RowKey\": \"1\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_dc382a3e-6ffd-492d-8317-878ef05160a8\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 2\r\n\r\nPOST + https://pytables3.table.cosmos.azure.com/uttable5ffa162c(PartitionKey='async_inserts',RowKey='2') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nX-HTTP-Method: + MERGE\r\nx-ms-date: Fri, 08 Oct 2021 18:56:53 GMT\r\nDate: Fri, 08 Oct 2021 + 18:56:53 GMT\r\n\r\n{\"PartitionKey\": \"async_inserts\", \"PartitionKey@odata.type\": + \"Edm.String\", \"RowKey\": \"2\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_dc382a3e-6ffd-492d-8317-878ef05160a8\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 3\r\n\r\nPOST + https://pytables3.table.cosmos.azure.com/uttable5ffa162c(PartitionKey='async_inserts',RowKey='3') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nX-HTTP-Method: + MERGE\r\nx-ms-date: Fri, 08 Oct 2021 18:56:53 GMT\r\nDate: Fri, 08 Oct 2021 + 18:56:53 GMT\r\n\r\n{\"PartitionKey\": \"async_inserts\", \"PartitionKey@odata.type\": + \"Edm.String\", \"RowKey\": \"3\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_dc382a3e-6ffd-492d-8317-878ef05160a8\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 4\r\n\r\nPOST + https://pytables3.table.cosmos.azure.com/uttable5ffa162c(PartitionKey='async_inserts',RowKey='4') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nX-HTTP-Method: + MERGE\r\nx-ms-date: Fri, 08 Oct 2021 18:56:53 GMT\r\nDate: Fri, 08 Oct 2021 + 18:56:53 GMT\r\n\r\n{\"PartitionKey\": \"async_inserts\", \"PartitionKey@odata.type\": + \"Edm.String\", \"RowKey\": \"4\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_dc382a3e-6ffd-492d-8317-878ef05160a8\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 5\r\n\r\nPOST + https://pytables3.table.cosmos.azure.com/uttable5ffa162c(PartitionKey='async_inserts',RowKey='5') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nX-HTTP-Method: + MERGE\r\nx-ms-date: Fri, 08 Oct 2021 18:56:53 GMT\r\nDate: Fri, 08 Oct 2021 + 18:56:53 GMT\r\n\r\n{\"PartitionKey\": \"async_inserts\", \"PartitionKey@odata.type\": + \"Edm.String\", \"RowKey\": \"5\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_dc382a3e-6ffd-492d-8317-878ef05160a8\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 6\r\n\r\nPOST + https://pytables3.table.cosmos.azure.com/uttable5ffa162c(PartitionKey='async_inserts',RowKey='6') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nX-HTTP-Method: + MERGE\r\nx-ms-date: Fri, 08 Oct 2021 18:56:53 GMT\r\nDate: Fri, 08 Oct 2021 + 18:56:53 GMT\r\n\r\n{\"PartitionKey\": \"async_inserts\", \"PartitionKey@odata.type\": + \"Edm.String\", \"RowKey\": \"6\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_dc382a3e-6ffd-492d-8317-878ef05160a8\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 7\r\n\r\nPOST + https://pytables3.table.cosmos.azure.com/uttable5ffa162c(PartitionKey='async_inserts',RowKey='7') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nX-HTTP-Method: + MERGE\r\nx-ms-date: Fri, 08 Oct 2021 18:56:53 GMT\r\nDate: Fri, 08 Oct 2021 + 18:56:53 GMT\r\n\r\n{\"PartitionKey\": \"async_inserts\", \"PartitionKey@odata.type\": + \"Edm.String\", \"RowKey\": \"7\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_dc382a3e-6ffd-492d-8317-878ef05160a8\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 8\r\n\r\nPOST + https://pytables3.table.cosmos.azure.com/uttable5ffa162c(PartitionKey='async_inserts',RowKey='8') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nX-HTTP-Method: + MERGE\r\nx-ms-date: Fri, 08 Oct 2021 18:56:53 GMT\r\nDate: Fri, 08 Oct 2021 + 18:56:53 GMT\r\n\r\n{\"PartitionKey\": \"async_inserts\", \"PartitionKey@odata.type\": + \"Edm.String\", \"RowKey\": \"8\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_dc382a3e-6ffd-492d-8317-878ef05160a8\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\nContent-ID: 9\r\n\r\nPOST + https://pytables3.table.cosmos.azure.com/uttable5ffa162c(PartitionKey='async_inserts',RowKey='9') + HTTP/1.1\r\nx-ms-version: 2019-02-02\r\nDataServiceVersion: 3.0\r\nContent-Type: + application/json\r\nAccept: application/json\r\nContent-Length: 124\r\nX-HTTP-Method: + MERGE\r\nx-ms-date: Fri, 08 Oct 2021 18:56:53 GMT\r\nDate: Fri, 08 Oct 2021 + 18:56:53 GMT\r\n\r\n{\"PartitionKey\": \"async_inserts\", \"PartitionKey@odata.type\": + \"Edm.String\", \"RowKey\": \"9\", \"RowKey@odata.type\": \"Edm.String\"}\r\n--changeset_dc382a3e-6ffd-492d-8317-878ef05160a8--\r\n\r\n--batch_d4e6ff69-6b3e-4f7f-b872-3e0a5aa70054--\r\n" + headers: + Accept: + - application/json + Content-Length: + - '6298' + Content-Type: + - multipart/mixed; boundary=batch_d4e6ff69-6b3e-4f7f-b872-3e0a5aa70054 + DataServiceVersion: + - '3.0' + Date: + - Fri, 08 Oct 2021 18:56:53 GMT + MaxDataServiceVersion: + - 3.0;NetFx + User-Agent: + - azsdk-python-data-tables/12.1.1 Python/3.7.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Fri, 08 Oct 2021 18:56:53 GMT + x-ms-version: + - '2019-02-02' + method: POST + uri: https://fake_cosmos_account.table.cosmos.azure.com/$batch + response: + body: + string: "--batchresponse_2b3192e8-8c4a-4489-87d8-d0614573973e\r\nContent-Type: + multipart/mixed; boundary=changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b\r\n\r\n--changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b\nContent-Type: + application/http\nContent-Transfer-Encoding: binary\n\nHTTP/1.1 204 No Content\r\nETag: + W/\"datetime'2021-10-08T18%3A56%3A54.0489735Z'\"\r\nContent-Type: application/json\r\nContent-ID: + 1\r\n\r\n\r\n--changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b\nContent-Type: + application/http\nContent-Transfer-Encoding: binary\n\nHTTP/1.1 204 No Content\r\nETag: + W/\"datetime'2021-10-08T18%3A56%3A54.0494855Z'\"\r\nContent-Type: application/json\r\nContent-ID: + 2\r\n\r\n\r\n--changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b\nContent-Type: + application/http\nContent-Transfer-Encoding: binary\n\nHTTP/1.1 204 No Content\r\nETag: + W/\"datetime'2021-10-08T18%3A56%3A54.0497927Z'\"\r\nContent-Type: application/json\r\nContent-ID: + 3\r\n\r\n\r\n--changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b\nContent-Type: + application/http\nContent-Transfer-Encoding: binary\n\nHTTP/1.1 204 No Content\r\nETag: + W/\"datetime'2021-10-08T18%3A56%3A54.0500999Z'\"\r\nContent-Type: application/json\r\nContent-ID: + 4\r\n\r\n\r\n--changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b\nContent-Type: + application/http\nContent-Transfer-Encoding: binary\n\nHTTP/1.1 204 No Content\r\nETag: + W/\"datetime'2021-10-08T18%3A56%3A54.0505095Z'\"\r\nContent-Type: application/json\r\nContent-ID: + 5\r\n\r\n\r\n--changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b\nContent-Type: + application/http\nContent-Transfer-Encoding: binary\n\nHTTP/1.1 204 No Content\r\nETag: + W/\"datetime'2021-10-08T18%3A56%3A54.0508167Z'\"\r\nContent-Type: application/json\r\nContent-ID: + 6\r\n\r\n\r\n--changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b\nContent-Type: + application/http\nContent-Transfer-Encoding: binary\n\nHTTP/1.1 204 No Content\r\nETag: + W/\"datetime'2021-10-08T18%3A56%3A54.0511239Z'\"\r\nContent-Type: application/json\r\nContent-ID: + 7\r\n\r\n\r\n--changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b\nContent-Type: + application/http\nContent-Transfer-Encoding: binary\n\nHTTP/1.1 204 No Content\r\nETag: + W/\"datetime'2021-10-08T18%3A56%3A54.0514311Z'\"\r\nContent-Type: application/json\r\nContent-ID: + 8\r\n\r\n\r\n--changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b\nContent-Type: + application/http\nContent-Transfer-Encoding: binary\n\nHTTP/1.1 204 No Content\r\nETag: + W/\"datetime'2021-10-08T18%3A56%3A54.0517383Z'\"\r\nContent-Type: application/json\r\nContent-ID: + 9\r\n\r\n\r\n--changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b\nContent-Type: + application/http\nContent-Transfer-Encoding: binary\n\nHTTP/1.1 204 No Content\r\nETag: + W/\"datetime'2021-10-08T18%3A56%3A54.0520455Z'\"\r\nContent-Type: application/json\r\nContent-ID: + 10\r\n\r\n\r\n--changesetresponse_e6acda92-1276-42f7-9005-a81dc1f6698b--\n--batchresponse_2b3192e8-8c4a-4489-87d8-d0614573973e--\r\n" + headers: + content-type: multipart/mixed; boundary=batchresponse_2b3192e8-8c4a-4489-87d8-d0614573973e + date: Fri, 08 Oct 2021 18:56:53 GMT + transfer-encoding: chunked + status: + code: 202 + message: Accepted + url: https://pytables3.table.cosmos.azure.com/$batch +- request: + body: null + headers: + Accept: + - application/json;odata=minimalmetadata + DataServiceVersion: + - '3.0' + Date: + - Fri, 08 Oct 2021 18:56:54 GMT + User-Agent: + - azsdk-python-data-tables/12.1.1 Python/3.7.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Fri, 08 Oct 2021 18:56:54 GMT + x-ms-version: + - '2019-02-02' + method: GET + uri: https://fake_cosmos_account.table.cosmos.azure.com/uttable5ffa162c()?$filter=PartitionKey%20eq%20'async_inserts' + response: + body: + string: '{"value":[{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A54.0489735Z''\"","PartitionKey":"async_inserts","RowKey":"0","Timestamp":"2021-10-08T18:56:54.0489735Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A54.0494855Z''\"","PartitionKey":"async_inserts","RowKey":"1","Timestamp":"2021-10-08T18:56:54.0494855Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A54.0497927Z''\"","PartitionKey":"async_inserts","RowKey":"2","Timestamp":"2021-10-08T18:56:54.0497927Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A54.0500999Z''\"","PartitionKey":"async_inserts","RowKey":"3","Timestamp":"2021-10-08T18:56:54.0500999Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A54.0505095Z''\"","PartitionKey":"async_inserts","RowKey":"4","Timestamp":"2021-10-08T18:56:54.0505095Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A54.0508167Z''\"","PartitionKey":"async_inserts","RowKey":"5","Timestamp":"2021-10-08T18:56:54.0508167Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A54.0511239Z''\"","PartitionKey":"async_inserts","RowKey":"6","Timestamp":"2021-10-08T18:56:54.0511239Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A54.0514311Z''\"","PartitionKey":"async_inserts","RowKey":"7","Timestamp":"2021-10-08T18:56:54.0514311Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A54.0517383Z''\"","PartitionKey":"async_inserts","RowKey":"8","Timestamp":"2021-10-08T18:56:54.0517383Z"},{"odata.etag":"W/\"datetime''2021-10-08T18%3A56%3A54.0520455Z''\"","PartitionKey":"async_inserts","RowKey":"9","Timestamp":"2021-10-08T18:56:54.0520455Z"}],"odata.metadata":"https://fake_cosmos_account.table.cosmos.azure.com/$metadata#uttable5ffa162c"}' + headers: + content-type: application/json;odata=minimalmetadata + date: Fri, 08 Oct 2021 18:56:53 GMT + transfer-encoding: chunked + status: + code: 200 + message: Ok + url: https://pytables3.table.cosmos.azure.com/uttable5ffa162c()?$filter=PartitionKey%20eq%20'async_inserts' +- request: + body: null + headers: + Accept: + - application/json;odata=minimalmetadata + DataServiceVersion: + - '3.0' + Date: + - Fri, 08 Oct 2021 18:56:54 GMT + User-Agent: + - azsdk-python-data-tables/12.1.1 Python/3.7.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Fri, 08 Oct 2021 18:56:54 GMT + x-ms-version: + - '2019-02-02' + method: GET + uri: https://fake_cosmos_account.table.cosmos.azure.com/Tables + response: + body: + string: '{"value":[{"TableName":"uttable5ffa162c"}],"odata.metadata":"https://fake_cosmos_account.table.cosmos.azure.com/$metadata#Tables"}' + headers: + content-type: application/json;odata=minimalmetadata + date: Fri, 08 Oct 2021 18:56:53 GMT + transfer-encoding: chunked + status: + code: 200 + message: Ok + url: https://pytables3.table.cosmos.azure.com/Tables +- request: + body: null + headers: + Accept: + - application/json + Date: + - Fri, 08 Oct 2021 18:56:54 GMT + User-Agent: + - azsdk-python-data-tables/12.1.1 Python/3.7.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Fri, 08 Oct 2021 18:56:54 GMT + x-ms-version: + - '2019-02-02' + method: DELETE + uri: https://fake_cosmos_account.table.cosmos.azure.com/Tables('uttable5ffa162c') + response: + body: + string: '' + headers: + date: Fri, 08 Oct 2021 18:56:54 GMT + status: + code: 204 + message: No Content + url: https://pytables3.table.cosmos.azure.com/Tables('uttable5ffa162c') +version: 1 diff --git a/sdk/tables/azure-data-tables/tests/test_table_batch_async.py b/sdk/tables/azure-data-tables/tests/test_table_batch_async.py index 72ef7640c636..390c781cc1f8 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_batch_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_batch_async.py @@ -750,3 +750,29 @@ async def test_batch_with_specialchar_partitionkey(self, tables_storage_account_ finally: await self._tear_down() + + @tables_decorator_async + async def test_async_batch_inserts(self, tables_storage_account_name, tables_primary_storage_account_key): + # Arrange + await self._set_up(tables_storage_account_name, tables_primary_storage_account_key) + try: + # Act + transaction_count = 10 + async def generate_entities(count): + for i in range(count): + yield ("upsert", {'PartitionKey': 'async_inserts', 'RowKey': str(i)}) + + batch = generate_entities(transaction_count) + transaction_result = await self.table.submit_transaction(batch) + + # Assert + self._assert_valid_batch_transaction(transaction_result, transaction_count) + assert 'etag' in transaction_result[0] + + entities = self.table.query_entities("PartitionKey eq 'async_inserts'") + entities = [e async for e in entities] + + # Assert + assert len(entities) == transaction_count + finally: + await self._tear_down() diff --git a/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos_async.py b/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos_async.py index b952be5c2d81..7d17c40c8be1 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos_async.py @@ -662,3 +662,29 @@ async def test_batch_with_specialchar_partitionkey(self, tables_cosmos_account_n finally: await self._tear_down() + + @cosmos_decorator_async + async def test_async_batch_inserts(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + # Arrange + await self._set_up(tables_cosmos_account_name, tables_primary_cosmos_account_key, url="cosmos") + try: + # Act + transaction_count = 10 + async def generate_entities(count): + for i in range(count): + yield ("upsert", {'PartitionKey': 'async_inserts', 'RowKey': str(i)}) + + batch = generate_entities(transaction_count) + transaction_result = await self.table.submit_transaction(batch) + + # Assert + self._assert_valid_batch_transaction(transaction_result, transaction_count) + assert 'etag' in transaction_result[0] + + entities = self.table.query_entities("PartitionKey eq 'async_inserts'") + entities = [e async for e in entities] + + # Assert + assert len(entities) == transaction_count + finally: + await self._tear_down()