Skip to content

Commit

Permalink
Adding the ability to create a container with analytical storage turn…
Browse files Browse the repository at this point in the history
…ed on. (#12408)

* Adding the ability to createa container with analytical storage turned on

* Updating the changelog

* disabling analytical storage tests while running against emulator (for the time being)

* fixing pylint issues

* Update sdk/cosmos/azure-cosmos/CHANGELOG.md

Co-authored-by: Steve Faulkner <[email protected]>

* changing func param to kwargs param

* removing whitespace that pylint doesn't like

* commenting out analytical storage unit tests out until we have emulator support

* noting in docstring that analytical storage can only be enabled on Synapse Link enabled accounts

* just kicking the tires to get the build working

Co-authored-by: Steve Faulkner <[email protected]>
Co-authored-by: annatisch <[email protected]>
  • Loading branch information
3 people authored Jul 22, 2020
1 parent 3f154bb commit 22bd8ce
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 6 deletions.
12 changes: 7 additions & 5 deletions sdk/cosmos/azure-cosmos/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
## 4.0.1 (Unreleased)

- Added deprecation warning for "lazy" indexing mode. The backend no longer allows creating containers with this mode and will set them to consistent instead.
- Fix for bug where options headers were not added to upsert_item function. Issue #11791 - thank you @aalapatirvbd.
- Fixed error raised when a non string ID is used in an item. It now raises TypeError rather than AttributeError. Issue #11793 - thank you @Rabbit994.
- Fixed #12570 - Thanks @sl-sandy.

** Bug fixes **
**New features**
- Added the ability to set the analytical storage TTL when creating a new container.

**Bug fixes**
- Fixed support for dicts as inputs for get_client APIs.
- Fixed Python 2/3 compatibility in query iterators.
- Fixed type hint error. Issue #12570 - Thanks @sl-sandy.
- Fixed bug where options headers were not added to upsert_item function. Issue #11791 - thank you @aalapatirvbd.
- Fixed error raised when a non string ID is used in an item. It now raises TypeError rather than AttributeError. Issue #11793 - thank you @Rabbit994.


## 4.0.0 (2020-05-20)
Expand Down Expand Up @@ -247,4 +250,3 @@ Version 4.0.0b1 is the first preview of our efforts to create a user-friendly an

- Supports proxy connection


14 changes: 13 additions & 1 deletion sdk/cosmos/azure-cosmos/azure/cosmos/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ def create_container(
has changed, and act according to the condition specified by the `match_condition` parameter.
:keyword ~azure.core.MatchConditions match_condition: The match condition to use upon the etag.
:keyword Callable response_hook: A callable invoked with the response metadata.
:keyword analytical_storage_ttl: Analytical store time to live (TTL) for items in the container. A value of
None leaves analytical storage off and a value of -1 turns analytical storage on with no TTL. Please
note that analytical storage can only be enabled on Synapse Link enabled accounts.
:returns: A `ContainerProxy` instance representing the new container.
:raises ~azure.cosmos.exceptions.CosmosHttpResponseError: The container creation failed.
:rtype: ~azure.cosmos.ContainerProxy
Expand Down Expand Up @@ -216,6 +219,10 @@ def create_container(
if conflict_resolution_policy is not None:
definition["conflictResolutionPolicy"] = conflict_resolution_policy

analytical_storage_ttl = kwargs.pop("analytical_storage_ttl", None)
if analytical_storage_ttl is not None:
definition["analyticalStorageTtl"] = analytical_storage_ttl

request_options = build_options(kwargs)
response_hook = kwargs.pop('response_hook', None)
if populate_query_metrics is not None:
Expand Down Expand Up @@ -266,11 +273,15 @@ def create_container_if_not_exists(
has changed, and act according to the condition specified by the `match_condition` parameter.
:keyword ~azure.core.MatchConditions match_condition: The match condition to use upon the etag.
:keyword Callable response_hook: A callable invoked with the response metadata.
:keyword analytical_storage_ttl: Analytical store time to live (TTL) for items in the container. A value of
None leaves analytical storage off and a value of -1 turns analytical storage on with no TTL. Please
note that analytical storage can only be enabled on Synapse Link enabled accounts.
:returns: A `ContainerProxy` instance representing the container.
:raises ~azure.cosmos.exceptions.CosmosHttpResponseError: The container read or creation failed.
:rtype: ~azure.cosmos.ContainerProxy
"""

analytical_storage_ttl = kwargs.pop("analytical_storage_ttl", None)
try:
container_proxy = self.get_container_client(id)
container_proxy.read(
Expand All @@ -287,7 +298,8 @@ def create_container_if_not_exists(
populate_query_metrics=populate_query_metrics,
offer_throughput=offer_throughput,
unique_key_policy=unique_key_policy,
conflict_resolution_policy=conflict_resolution_policy
conflict_resolution_policy=conflict_resolution_policy,
analytical_storage_ttl=analytical_storage_ttl
)

@distributed_trace
Expand Down
65 changes: 65 additions & 0 deletions sdk/cosmos/azure-cosmos/test/test_crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -2605,6 +2605,71 @@ def test_get_resource_with_dictionary_and_object(self):
read_permission = created_user.get_permission(created_permission.properties)
self.assertEqual(read_permission.id, created_permission.id)

# Temporarily commenting analytical storage tests until emulator support comes.
# def test_create_container_with_analytical_store_off(self):
# # don't run test, for the time being, if running against the emulator
# if 'localhost' in self.host or '127.0.0.1' in self.host:
# return

# created_db = self.databaseForTest
# collection_id = 'test_create_container_with_analytical_store_off_' + str(uuid.uuid4())
# collection_indexing_policy = {'indexingMode': 'consistent'}
# created_recorder = RecordDiagnostics()
# created_collection = created_db.create_container(id=collection_id,
# indexing_policy=collection_indexing_policy,
# partition_key=PartitionKey(path="/pk", kind="Hash"),
# response_hook=created_recorder)
# properties = created_collection.read()
# ttl_key = "analyticalStorageTtl"
# self.assertTrue(ttl_key not in properties or properties[ttl_key] == None)

# def test_create_container_with_analytical_store_on(self):
# # don't run test, for the time being, if running against the emulator
# if 'localhost' in self.host or '127.0.0.1' in self.host:
# return

# created_db = self.databaseForTest
# collection_id = 'test_create_container_with_analytical_store_on_' + str(uuid.uuid4())
# collection_indexing_policy = {'indexingMode': 'consistent'}
# created_recorder = RecordDiagnostics()
# created_collection = created_db.create_container(id=collection_id,
# analytical_storage_ttl=-1,
# indexing_policy=collection_indexing_policy,
# partition_key=PartitionKey(path="/pk", kind="Hash"),
# response_hook=created_recorder)
# properties = created_collection.read()
# ttl_key = "analyticalStorageTtl"
# self.assertTrue(ttl_key in properties and properties[ttl_key] == -1)

# def test_create_container_if_not_exists_with_analytical_store_on(self):
# # don't run test, for the time being, if running against the emulator
# if 'localhost' in self.host or '127.0.0.1' in self.host:
# return

# # first, try when we know the container doesn't exist.
# created_db = self.databaseForTest
# collection_id = 'test_create_container_if_not_exists_with_analytical_store_on_' + str(uuid.uuid4())
# collection_indexing_policy = {'indexingMode': 'consistent'}
# created_recorder = RecordDiagnostics()
# created_collection = created_db.create_container_if_not_exists(id=collection_id,
# analytical_storage_ttl=-1,
# indexing_policy=collection_indexing_policy,
# partition_key=PartitionKey(path="/pk", kind="Hash"),
# response_hook=created_recorder)
# properties = created_collection.read()
# ttl_key = "analyticalStorageTtl"
# self.assertTrue(ttl_key in properties and properties[ttl_key] == -1)

# # next, try when we know the container DOES exist. This way both code paths are tested.
# created_collection = created_db.create_container_if_not_exists(id=collection_id,
# analytical_storage_ttl=-1,
# indexing_policy=collection_indexing_policy,
# partition_key=PartitionKey(path="/pk", kind="Hash"),
# response_hook=created_recorder)
# properties = created_collection.read()
# ttl_key = "analyticalStorageTtl"
# self.assertTrue(ttl_key in properties and properties[ttl_key] == -1)

def _MockExecuteFunction(self, function, *args, **kwargs):
self.last_headers.append(args[4].headers[HttpHeaders.PartitionKey]
if HttpHeaders.PartitionKey in args[4].headers else '')
Expand Down

0 comments on commit 22bd8ce

Please sign in to comment.