Skip to content

Commit bac634e

Browse files
author
Srinath Narayanan
committed
moved methods to correct location
1 parent 540a8e9 commit bac634e

File tree

5 files changed

+109
-134
lines changed

5 files changed

+109
-134
lines changed

sdk/cosmos/azure-cosmos/HISTORY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Version 4.0.0b3:
44

5-
- Added `create_if_not_exists()` functionality to container and database.
5+
- Added `create_database_if_not_exists()` and `create_container_if_not_exists` functionalities to CosmosClient and Database respectively.
66

77
## Version 4.0.0b2:
88

sdk/cosmos/azure-cosmos/azure/cosmos/container.py

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ def __init__(self, client_connection, database_link, id, properties=None): # py
6363
self.client_connection = client_connection
6464
self.id = id
6565
self._properties = properties
66-
self.database_link = database_link
6766
self.container_link = u"{}/colls/{}".format(database_link, self.id)
6867
self._is_system_key = None
6968
self._scripts = None # type: Optional[ScriptsProxy]
@@ -152,79 +151,6 @@ def read(
152151

153152
return cast('Dict[str, Any]', self._properties)
154153

155-
@distributed_trace
156-
def create_if_not_exists(
157-
self,
158-
partition_key, # type: Any
159-
indexing_policy=None, # type: Optional[Dict[str, Any]]
160-
default_ttl=None, # type: Optional[int]
161-
populate_query_metrics=None, # type: Optional[bool]
162-
offer_throughput=None, # type: Optional[int]
163-
unique_key_policy=None, # type: Optional[Dict[str, Any]]
164-
conflict_resolution_policy=None, # type: Optional[Dict[str, Any]]
165-
**kwargs # type: Any
166-
):
167-
# type: (...) -> ContainerProxy
168-
"""
169-
Create the container if it does not exist already.
170-
171-
If the container already exists, it is returned.
172-
173-
:param partition_key: The partition key to use for the container.
174-
:param indexing_policy: The indexing policy to apply to the container.
175-
:param default_ttl: Default time to live (TTL) for items in the container. If unspecified, items do not expire.
176-
:param session_token: Token for use with Session consistency.
177-
:param initial_headers: Initial headers to be sent as part of the request.
178-
:param access_condition: Conditions Associated with the request.
179-
:param populate_query_metrics: Enable returning query metrics in response headers.
180-
:param offer_throughput: The provisioned throughput for this offer.
181-
:param unique_key_policy: The unique key policy to apply to the container.
182-
:param conflict_resolution_policy: The conflict resolution policy to apply to the container.
183-
:param request_options: Dictionary of additional properties to be used for the request.
184-
:param response_hook: a callable invoked with the response metadata
185-
:returns: A `ContainerProxy` instance representing the container.
186-
:raise CosmosHttpResponseError: The container read or creation failed.
187-
:rtype: ~azure.cosmos.container.ContainerProxy
188-
"""
189-
190-
response_hook = kwargs.pop('response_hook', None)
191-
try:
192-
collection_link = self.container_link
193-
self._properties = self.client_connection.ReadContainer(
194-
collection_link, **kwargs
195-
)
196-
197-
if response_hook:
198-
response_hook(self.client_connection.last_response_headers, self._properties)
199-
return self
200-
except CosmosResourceNotFoundError:
201-
definition = dict(id=self.id) # type: Dict[str, Any]
202-
if partition_key:
203-
definition["partitionKey"] = partition_key
204-
if indexing_policy:
205-
definition["indexingPolicy"] = indexing_policy
206-
if default_ttl:
207-
definition["defaultTtl"] = default_ttl
208-
if unique_key_policy:
209-
definition["uniqueKeyPolicy"] = unique_key_policy
210-
if conflict_resolution_policy:
211-
definition["conflictResolutionPolicy"] = conflict_resolution_policy
212-
213-
request_options = build_options(kwargs)
214-
if populate_query_metrics is not None:
215-
request_options["populateQueryMetrics"] = populate_query_metrics
216-
if offer_throughput is not None:
217-
request_options["offerThroughput"] = offer_throughput
218-
219-
data = self.client_connection.CreateContainer(
220-
database_link=self.database_link, collection=definition, options=request_options, **kwargs
221-
)
222-
223-
if response_hook:
224-
response_hook(self.client_connection.last_response_headers, data)
225-
226-
return ContainerProxy(self.client_connection, self.database_link, data["id"], properties=data)
227-
228154
@distributed_trace
229155
def read_item(
230156
self,

sdk/cosmos/azure-cosmos/azure/cosmos/cosmos_client.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from ._base import build_options
3232
from .database import DatabaseProxy
3333
from .documents import ConnectionPolicy, DatabaseAccount
34+
from .errors import CosmosResourceNotFoundError
3435

3536
__all__ = ("CosmosClient",)
3637

@@ -244,6 +245,47 @@ def create_database( # pylint: disable=redefined-builtin
244245
response_hook(self.client_connection.last_response_headers)
245246
return DatabaseProxy(self.client_connection, id=result["id"], properties=result)
246247

248+
@distributed_trace
249+
def create_database_if_not_exists( # pylint: disable=redefined-builtin
250+
self,
251+
id, # type: str
252+
populate_query_metrics=None, # type: Optional[bool]
253+
offer_throughput=None, # type: Optional[int]
254+
**kwargs # type: Any
255+
):
256+
# type: (...) -> DatabaseProxy
257+
"""
258+
Create the database if it does not exist already.
259+
260+
If the database already exists, it is returned.
261+
262+
:param id: ID (name) of the database to read or create.
263+
:param str session_token: Token for use with Session consistency.
264+
:param dict(str, str) initial_headers: Initial headers to be sent as part of the request.
265+
:param dict(str, str) access_condition: Conditions Associated with the request.
266+
:param bool populate_query_metrics: Enable returning query metrics in response headers.
267+
:param int offer_throughput: The provisioned throughput for this offer.
268+
:param dict(str, Any) request_options: Dictionary of additional properties to be used for the request.
269+
:param Callable response_hook: a callable invoked with the response metadata
270+
:returns: A DatabaseProxy instance representing the database.
271+
:rtype: ~azure.cosmos.database.DatabaseProxy
272+
:raise CosmosHttpResponseError: The database read or creation failed.
273+
"""
274+
try:
275+
database_proxy = self.get_database_client(id)
276+
database_proxy.read(
277+
populate_query_metrics=populate_query_metrics,
278+
**kwargs
279+
)
280+
return database_proxy
281+
except CosmosResourceNotFoundError:
282+
return self.create_database(
283+
id,
284+
populate_query_metrics=populate_query_metrics,
285+
offer_throughput=offer_throughput,
286+
**kwargs
287+
)
288+
247289
def get_database_client(self, database):
248290
# type: (Union[str, DatabaseProxy, Dict[str, Any]]) -> DatabaseProxy
249291
"""

sdk/cosmos/azure-cosmos/azure/cosmos/database.py

Lines changed: 56 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -141,55 +141,6 @@ def read(self, populate_query_metrics=None, **kwargs):
141141

142142
return cast('Dict[str, Any]', self._properties)
143143

144-
@distributed_trace
145-
def create_if_not_exists( # pylint: disable=redefined-builtin
146-
self,
147-
populate_query_metrics=None, # type: Optional[bool]
148-
offer_throughput=None, # type: Optional[int]
149-
**kwargs # type: Any
150-
):
151-
# type: (...) -> DatabaseProxy
152-
"""
153-
Create the database if it does not exist already.
154-
155-
If the database already exists, it is returned.
156-
157-
:param str session_token: Token for use with Session consistency.
158-
:param dict(str, str) initial_headers: Initial headers to be sent as part of the request.
159-
:param dict(str, str) access_condition: Conditions Associated with the request.
160-
:param bool populate_query_metrics: Enable returning query metrics in response headers.
161-
:param int offer_throughput: The provisioned throughput for this offer.
162-
:param dict(str, Any) request_options: Dictionary of additional properties to be used for the request.
163-
:param Callable response_hook: a callable invoked with the response metadata
164-
:returns: A DatabaseProxy instance representing the database.
165-
:rtype: ~azure.cosmos.database.DatabaseProxy
166-
:raise CosmosHttpResponseError: The database read or creation failed.
167-
"""
168-
response_hook = kwargs.pop('response_hook', None)
169-
try:
170-
from .cosmos_client import CosmosClient
171-
172-
database_link = CosmosClient._get_database_link(self)
173-
self._properties = self.client_connection.ReadDatabase(
174-
database_link, **kwargs
175-
)
176-
177-
if response_hook:
178-
response_hook(self.client_connection.last_response_headers, self._properties)
179-
180-
return self
181-
except CosmosResourceNotFoundError:
182-
request_options = build_options(kwargs)
183-
if populate_query_metrics is not None:
184-
request_options["populateQueryMetrics"] = populate_query_metrics
185-
if offer_throughput is not None:
186-
request_options["offerThroughput"] = offer_throughput
187-
188-
result = self.client_connection.CreateDatabase(database=dict(id=self.id), options=request_options, **kwargs)
189-
if response_hook:
190-
response_hook(self.client_connection.last_response_headers)
191-
return DatabaseProxy(self.client_connection, id=result["id"], properties=result)
192-
193144
@distributed_trace
194145
def create_container(
195146
self,
@@ -271,6 +222,62 @@ def create_container(
271222

272223
return ContainerProxy(self.client_connection, self.database_link, data["id"], properties=data)
273224

225+
@distributed_trace
226+
def create_container_if_not_exists(
227+
self,
228+
id, # type: str # pylint: disable=redefined-builtin
229+
partition_key, # type: Any
230+
indexing_policy=None, # type: Optional[Dict[str, Any]]
231+
default_ttl=None, # type: Optional[int]
232+
populate_query_metrics=None, # type: Optional[bool]
233+
offer_throughput=None, # type: Optional[int]
234+
unique_key_policy=None, # type: Optional[Dict[str, Any]]
235+
conflict_resolution_policy=None, # type: Optional[Dict[str, Any]]
236+
**kwargs # type: Any
237+
):
238+
# type: (...) -> ContainerProxy
239+
"""
240+
Create the container if it does not exist already.
241+
242+
If the container already exists, it is returned.
243+
244+
:param id: ID (name) of container to read or create.
245+
:param partition_key: The partition key to use for the container.
246+
:param indexing_policy: The indexing policy to apply to the container.
247+
:param default_ttl: Default time to live (TTL) for items in the container. If unspecified, items do not expire.
248+
:param session_token: Token for use with Session consistency.
249+
:param initial_headers: Initial headers to be sent as part of the request.
250+
:param access_condition: Conditions Associated with the request.
251+
:param populate_query_metrics: Enable returning query metrics in response headers.
252+
:param offer_throughput: The provisioned throughput for this offer.
253+
:param unique_key_policy: The unique key policy to apply to the container.
254+
:param conflict_resolution_policy: The conflict resolution policy to apply to the container.
255+
:param request_options: Dictionary of additional properties to be used for the request.
256+
:param response_hook: a callable invoked with the response metadata
257+
:returns: A `ContainerProxy` instance representing the container.
258+
:raise CosmosHttpResponseError: The container read or creation failed.
259+
:rtype: ~azure.cosmos.container.ContainerProxy
260+
"""
261+
262+
try:
263+
container_proxy = self.get_container_client(id)
264+
container_proxy.read(
265+
populate_query_metrics=populate_query_metrics,
266+
**kwargs
267+
)
268+
return container_proxy
269+
except CosmosResourceNotFoundError:
270+
return self.create_container(
271+
id=id,
272+
partition_key=partition_key,
273+
indexing_policy=indexing_policy,
274+
default_ttl=default_ttl,
275+
populate_query_metrics=populate_query_metrics,
276+
offer_throughput=offer_throughput,
277+
unique_key_policy=unique_key_policy,
278+
conflict_resolution_policy=conflict_resolution_policy
279+
)
280+
274281
@distributed_trace
275282
def delete_container(
276283
self,

sdk/cosmos/azure-cosmos/test/crud_tests.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,15 +136,15 @@ def test_database_crud(self):
136136
self.__AssertHTTPFailureWithStatus(StatusCodes.NOT_FOUND,
137137
read_db.read)
138138

139-
database_proxy = read_db.create_if_not_exists(offer_throughput=10000)
140-
self.assertEqual(read_db.id, database_proxy.id)
141-
self.assertEquals(database_proxy.read_offer().offer_throughput, 10000)
139+
database_proxy = self.client.create_database_if_not_exists(id=database_id, offer_throughput=10000)
140+
self.assertEqual(database_id, database_proxy.id)
141+
self.assertEquals(10000, database_proxy.read_offer().offer_throughput)
142142

143-
database_proxy = read_db.create_if_not_exists(offer_throughput=9000)
144-
self.assertEqual(read_db.id, database_proxy.id)
145-
self.assertEquals(database_proxy.read_offer().offer_throughput, 10000)
143+
database_proxy = self.client.create_database_if_not_exists(id=database_id, offer_throughput=9000)
144+
self.assertEqual(database_id, database_proxy.id)
145+
self.assertEquals(10000, database_proxy.read_offer().offer_throughput)
146146

147-
self.client.delete_database(read_db.id)
147+
self.client.delete_database(database_id)
148148

149149
@pytest.mark.skip("skipping as the TestResources subscription doesn't support this offer")
150150
def test_database_level_offer_throughput(self):
@@ -246,11 +246,11 @@ def test_collection_crud(self):
246246
self.__AssertHTTPFailureWithStatus(StatusCodes.NOT_FOUND,
247247
created_container.read)
248248

249-
container_proxy = created_container.create_if_not_exists(partition_key=PartitionKey(path='/id', kind='Hash'))
250-
self.assertEqual(created_container.id, container_proxy.id)
249+
container_proxy = created_db.create_container_if_not_exists(id=created_collection.id, partition_key=PartitionKey(path='/id', kind='Hash'))
250+
self.assertEqual(created_collection.id, container_proxy.id)
251251
self.assertDictEqual(PartitionKey(path='/id', kind='Hash'), container_proxy._properties['partitionKey'])
252252

253-
container_proxy = created_container.create_if_not_exists(partition_key=created_properties['partitionKey'])
253+
container_proxy = created_db.create_container_if_not_exists(id=created_collection.id, partition_key=created_properties['partitionKey'])
254254
self.assertEqual(created_container.id, container_proxy.id)
255255
self.assertDictEqual(PartitionKey(path='/id', kind='Hash'), container_proxy._properties['partitionKey'])
256256

0 commit comments

Comments
 (0)