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 の初期化

client = CosmosClient(endpoint, key)

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

新しいデータベース作成

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

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

新しいコンテナー作成

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

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

コンテナーに追加

for family_item in family_items_to_create:
    container.create_item(body=family_item)

ここで、Family_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)))

##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 にその変更内容がしっかり反映されているか否かです。わずかですが、こんな風に変えてみましょう。

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

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

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 を見てみると、新しい名前でデータベースができ、その中に同じ内容のものが入ったのが分かります。

所感

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