Python から Azure CosmosDB を操作する Part.2

前回の続きで、もう少しコードを深掘りしていきたいと思います。
前回議事→https://qiita.com/komiyasa/items/ae34fd9fec46c0e01b35

#チュートリアルのコード
以下は全体間。この全体では、データベースの名前、コンテナーの名前を設定します。具体的な中身については別の Python ファイルで設定しているみたいです。

```Program.py
from azure.cosmos import exceptions, CosmosClient, PartitionKey
import family

# Initialize the Cosmos client
endpoint = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

# <create_cosmos_client>
client = CosmosClient(endpoint, key)
# </create_cosmos_client>

# Create a database
# <create_database_if_not_exists>
database_name = 'AzureSampleFamilyDatabase'
database = client.create_database_if_not_exists(id=database_name)
# </create_database_if_not_exists>

# Create a container
# Using a good partition key improves the performance of database operations.
# <create_container_if_not_exists>
container_name = 'FamilyContainer'
container = database.create_container_if_not_exists(
    id=container_name, 
    partition_key=PartitionKey(path="/lastName"),
    offer_throughput=400
)
# </create_container_if_not_exists>


# Add items to the container
family_items_to_create = [family.get_andersen_family_item(), family.get_johnson_family_item(), family.get_smith_family_item(), family.get_wakefield_family_item()]

 # <create_item>
for family_item in family_items_to_create:
    container.create_item(body=family_item)
# </create_item>

# Read items (key value lookups by partition key and id, aka point reads)
# <read_item>
for family in family_items_to_create:
    item_response = container.read_item(item=family['id'], partition_key=family['lastName'])
    request_charge = container.client_connection.last_response_headers['x-ms-request-charge']
    print('Read item with id {0}. Operation consumed {1} request units'.format(item_response['id'], (request_charge)))
# </read_item>

# Query these items using the SQL query syntax. 
# Specifying the partition key value in the query allows Cosmos DB to retrieve data only from the relevant partitions, which improves performance
# <query_items>
query = "SELECT * FROM c WHERE c.lastName IN ('Wakefield', 'Andersen')"

items = list(container.query_items(
    query=query,
    enable_cross_partition_query=True
))

request_charge = container.client_connection.last_response_headers['x-ms-request-charge']

print('Query returned {0} items. Operation consumed {1} request units'.format(len(items), request_charge))
# </query_items>
```

##CosmosClient の初期化

```python
client = CosmosClient(endpoint, key)
```
ここでエンドポイント、Key を設定しています。Azure Portal から、デプロイした Cosmos DB の Key を取得することで、client に値をセットします。

##新しいデータベース作成

```python
database_name = 'AzureSampleFamilyDatabase'
database = client.create_database_if_not_exists(id=database_name)
```

もしかぶっている名前がなければ、という条件を入れつつ、新しいデータベースを作成しています。ここでは `AzureSampleFamilyDatabase` というデータベースを作成しました。

##新しいコンテナー作成

```python
container_name = 'FamilyContainer'
container = database.create_container_if_not_exists(
    id=container_name, 
    partition_key=PartitionKey(path="/lastName"),
    offer_throughput=400
)
```

ここで `FamilyContainer` という名前のコンテナーを作成します。これももしなかったら、という条件付きです。

##コンテナーに追加

```python
for family_item in family_items_to_create:
    container.create_item(body=family_item)
```
ここで、`Family_item` の値をコンテナーへ入力します。

##ポイント読み取り

```python
for family in family_items_to_create:
    item_response = container.read_item(item=family['id'], partition_key=family['lastName'])
    request_charge = container.client_connection.last_response_headers['x-ms-request-charge']
    print('Read item with id {0}. Operation consumed {1} request units'.format(item_response['id'], (request_charge)))

##SQL クエリ構文を使用して、クエリ実行
query = "SELECT * FROM c WHERE c.lastName IN ('Wakefield', 'Andersen')"

items = list(container.query_items(
    query=query,
    enable_cross_partition_query=True
))

request_charge = container.client_connection.last_response_headers['x-ms-request-charge']

print('Query returned {0} items. Operation consumed {1} request units'.format(len(items), request_charge))
```

#ちょっとアレンジ
一番簡単にできるアレンジは、このコードにあるデータベース名、コンテナー名を変えてみると、Azure Portal にその変更内容がしっかり反映されているか否かです。わずかですが、こんな風に変えてみましょう。

```python
database_name = 'AzureSampleFamilyDatabase2'
database = client.create_database_if_not_exists(id=database_name)
```

コマンドの出力結果は以下になりました。

```terminal
PS C:\Users\komiyasa\Val\sample\azure-cosmos-db-python-getting-started> python .\cosmos_get_started.py
Read item with id Andersen_c23dcf0d-de55-43eb-afbe-e102ebb22dcc. Operation consumed 1 request units
Read item with id Smith_efc4369e-0c4b-4609-8dfc-6799df71f07d. Operation consumed 1 request units
Read item with id Johnson_d84a50c0-ce2e-4b53-a3e9-08104a1a1b7d. Operation consumed 1 request units
Read item with id Wakefield_a667cfc4-a266-4b63-a104-a27e636039e8. Operation consumed 1 request units
```

Azure Portal を見てみると、新しい名前でデータベースができ、その中に同じ内容のものが入ったのが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/7ae0e079-3b42-f5a2-53d4-d041fd0f918d.png)

#所感
使い勝手が非常によく、感覚的にデプロイできるので便利なサンプルコードです。
次回は、Azure Python SDK を使用した、SQL でいうところの、Delete/Update の方法を確認したいと思います。