クイックスタート: MongoDB ドライバーを使用する Python 用 Azure Cosmos DB for MongoDB
適用対象: MongoDB
PyMongo パッケージの使用を開始して、Azure Cosmos DB リソース内にデータベース、コレクション、ドキュメントを作成します。 以下の手順に従って、パッケージをインストールし、基本タスクのコード例を試してみましょう。
Note
コード スニペットの例は、Python プロジェクトとして GitHub 上で使用できます。
このクイックスタートでは、Python 用のオープンソース MongoDB クライアント ドライバーの 1 つである PyMongo を使用して、Azure Cosmos DB の MongoDB 用 API と通信します。 また、MongoDB 拡張機能コマンドを使用します。このコマンドは、Azure Cosmos DB 容量モデルに固有のデータベース リソースを作成および取得する際に役立ちます。
前提条件
- アクティブなサブスクリプションが含まれる Azure アカウント。 無料でアカウントを作成できます。
- python=3.8.10
- Azure コマンド ライン インターフェイス (CLI) または Azure PowerShell
前提条件のチェック
- ターミナルまたはコマンド ウィンドウで
python --version
を実行して、Python が最新バージョンであることを確認します。 az --version
(Azure CLI) またはGet-Module -ListAvailable Az*
(Azure PowerShell) を実行して、適切な Azure コマンド ライン ツールがインストールされていることを確認します。
設定
このセクションでは、Azure Cosmos DB アカウントを作成し、MongoDB npm パッケージを使用するプロジェクトを設定する手順について説明します。
Azure Cosmos DB アカウントを作成する
このクイック スタートでは、MongoDB 用 API を使って Azure Cosmos DB アカウントを 1 つ作成します。
accountName、resourceGroupName、および location のシェル変数を作成します。
# Variable for resource group name resourceGroupName="msdocs-cosmos-quickstart-rg" location="westus" # Variable for account name with a randomnly generated suffix let suffix=$RANDOM*$RANDOM accountName="msdocs-$suffix"
az login
コマンドを使用して Azure CLI にサインインします (まだ行っていない場合)。az group create
コマンドを使用して、サブスクリプションに新しいリソース グループを作成します。az group create \ --name $resourceGroupName \ --location $location
az cosmosdb create
コマンドを使って、既定の設定で新しい Azure Cosmos DB for MongoDB アカウントを作成します。az cosmosdb create \ --resource-group $resourceGroupName \ --name $accountName \ --locations regionName=$location --kind MongoDB
MongoDB 接続文字列の取得
az cosmosdb keys list
コマンドを使って、アカウントの接続文字列の一覧から MongoDB 用 API の接続文字列を見つけます。az cosmosdb keys list --type connection-strings \ --resource-group $resourceGroupName \ --name $accountName
"主キー" の値を記録します。 これらの資格情報は後で使用します。
新しい Python アプリを作成する
任意のターミナルを使用して新しい空のフォルダーを作成し、ディレクトリをそのフォルダーに変更します。
Note
完成したコードが必要な場合は、完全な例を含むサンプル コード スニペット リポジトリをダウンロードまたはフォークして複製します。 また、Azure Cloud Shell のリポジトリで
git clone
を実行して、このクイックスタートに示されているステップに従うこともできます。PyMongo パッケージと python-dotenv パッケージが一覧表示される requirements.txt ファイルを作成します。
# requirements.txt pymongo python-dotenv
仮想環境を作成し、パッケージをインストールします。
# py -3 uses the global python interpreter. You can also use python3 -m venv .venv. py -3 -m venv .venv source .venv/Scripts/activate pip install -r requirements.txt
環境変数を構成する
コード内で接続文字列の値を使用するには、アプリケーションを実行しているローカル環境でこの値を設定します。 環境変数を設定するには、任意のターミナルを使用して次のコマンドを実行します。
$env:COSMOS_CONNECTION_STRING = "<cosmos-connection-string>"
オブジェクト モデル
MongoDB 用 API のリソースの階層と、これらのリソースの作成とアクセスに使用されるオブジェクト モデルについて説明します。 Azure Cosmos DB によって、アカウント、データベース、コレクション、ドキュメントで構成される階層内にリソースが作成されます。
上部に Azure Cosmos DB アカウントを示す階層図。 このアカウントには 2 つの子データベース シャードがあります。 一方のデータベース シャードには、2 つの子コレクション シャードが含まれています。 もう一方のデータベース シャードには、1 つの子コレクション シャードが含まれています。 その 1 つのコレクション シャードには、3 つの子ドキュメント シャードがあります。
リソースの各種類は、Python クラスによって表されます。 最も一般的なクラスを次に示します。
MongoClient - PyMongo を使用する最初のステップは、Azure Cosmos DB の MongoDB 用 API に接続する MongoClient を作成することです。 このクライアント オブジェクトは、サービスに対する要求の構成と実行に使用されます。
データベース - Azure Cosmos DB の MongoDB 用 API では、1 つ以上の独立したデータベースをサポートできます。
コレクション - データベースには 1 つまたは複数のコレクションを格納できます。 コレクションは MongoDB に格納されているドキュメントのグループであり、リレーショナル データベースのテーブルとほぼ同等と考えられます。
ドキュメント - ドキュメントはキーと値のペアのセットです。 ドキュメントには動的スキーマがあります。 動的スキーマとは、同じコレクション内のドキュメントに同じフィールドまたは構造のセットが必要ないことを意味します。 また、コレクションのドキュメント内の共通フィールドには、さまざまな種類のデータが含まれている場合があります。
エンティティの階層について詳しくは、「Azure Cosmos DB リソース モデル」の記事を参照してください。
コード例
この記事で説明されているサンプル コードでは、products
という名前のコレクションを使用して adventureworks
という名前のデータベースを作成します。 products
コレクションは、名前、カテゴリ、数量、販売インジケーターなどの製品の詳細が含まれるように設計されています。 各製品には、一意の識別子も含まれています。 完全なサンプル コードは https://github.com/Azure-Samples/azure-cosmos-db-mongodb-python-getting-started/tree/main/001-quickstart/ にあります。
次のステップでは、データベースでシャーディングが使用されず、PyMongo ドライバーを使用した同期アプリケーションを示しています。 非同期アプリケーションの場合は、Motor ドライバーを使用します。
クライアントを認証する
プロジェクト ディレクトリで、run.py ファイルを作成します。 使用するパッケージ (PyMongo パッケージや python-dotenv パッケージなど) を参照するために、エディターで require ステートメントを追加します。
import os import sys from random import randint import pymongo from dotenv import load_dotenv
.env ファイルで定義されている環境変数から接続情報を取得します。
load_dotenv() CONNECTION_STRING = os.environ.get("COSMOS_CONNECTION_STRING")
コードで使用する定数を定義します。
DB_NAME = "adventureworks" COLLECTION_NAME = "products"
Azure Cosmos DB の MongoDB 用 API に接続する
MongoClient オブジェクトを使用して、Azure Cosmos DB for MongoDB リソースに接続します。 この接続メソッドは、データベースへの参照を返します。
client = pymongo.MongoClient(CONNECTION_STRING)
データベースの取得
list_database_names メソッドを使用して、データベースが存在するかどうかを確認します。 データベースが存在しない場合は、データベースを作成する拡張機能コマンドを使用して、プロビジョニングされたスループットを指定して作成します。
# Create database if it doesn't exist
db = client[DB_NAME]
if DB_NAME not in client.list_database_names():
# Create a database with 400 RU throughput that can be shared across
# the DB's collections
db.command({"customAction": "CreateDatabase", "offerThroughput": 400})
print("Created db '{}' with shared throughput.\n".format(DB_NAME))
else:
print("Using database: '{}'.\n".format(DB_NAME))
コレクションの取得
list_collection_names メソッドを使用して、コレクションが存在するかどうかを確認します。 コレクションが存在しない場合は、コレクションを作成する拡張機能コマンドを使用して作成します。
# Create collection if it doesn't exist
collection = db[COLLECTION_NAME]
if COLLECTION_NAME not in db.list_collection_names():
# Creates a unsharded collection that uses the DBs shared throughput
db.command(
{"customAction": "CreateCollection", "collection": COLLECTION_NAME}
)
print("Created collection '{}'.\n".format(COLLECTION_NAME))
else:
print("Using collection: '{}'.\n".format(COLLECTION_NAME))
インデックスを作成する
コレクションを更新する拡張機能コマンドを使用して、インデックスを作成します。 コレクションを作成する拡張機能コマンドでインデックスを設定することもできます。 この例では、後で製品名のカーソル クラス sort メソッドを使用して並べ替えられるように、インデックスを name
プロパティに設定します。
indexes = [
{"key": {"_id": 1}, "name": "_id_1"},
{"key": {"name": 2}, "name": "_id_2"},
]
db.command(
{
"customAction": "UpdateCollection",
"collection": COLLECTION_NAME,
"indexes": indexes,
}
)
print("Indexes are: {}\n".format(sorted(collection.index_information())))
ドキュメントの作成
adventureworks
データベースの product プロパティを使用してドキュメントを作成します。
- category プロパティ。 このプロパティは、論理パーティション キーとして使用できます。
- name プロパティ。
- インベントリの quantity プロパティ。
- sale プロパティ。製品が販売されているかどうかを示します。
"""Create new document and upsert (create or replace) to collection"""
product = {
"category": "gear-surf-surfboards",
"name": "Yamba Surfboard-{}".format(randint(50, 5000)),
"quantity": 1,
"sale": False,
}
result = collection.update_one(
{"name": product["name"]}, {"$set": product}, upsert=True
)
print("Upserted document with _id {}\n".format(result.upserted_id))
コレクション レベルの操作 update_one を呼び出して、コレクション内にドキュメントを作成します。 この例では、新しいドキュメントを作成する代わりにアップサートします。 この例では、製品名がランダムであるため、アップサートは必要ありません。 ただし、コードを複数回実行し、製品名が同じである場合に備えて、アップサートすることをお勧めします。
update_one
操作の結果には、後続の操作で使用できる _id
フィールドの値が含まれます。 _id プロパティは自動的に作成されています。
1 つのドキュメントを取得する
find_one メソッドを使用して、ドキュメントを取得します。
doc = collection.find_one({"_id": result.upserted_id})
print("Found a document with _id {}: {}\n".format(result.upserted_id, doc))
Azure Cosmos DB では、一意識別子 (_id
) とパーティション キーの両方を使用して、低コストのポイント読み取り操作を実行できます。
ドキュメントにクエリを実行する
ドキュメントを挿入した後、クエリを実行して、特定のフィルターに一致するすべてのドキュメントを取得できます。 この例では、特定のカテゴリ gear-surf-surfboards
に一致するすべてのドキュメントを検索します。 クエリを定義したら、Collection.find
を呼び出して Cursor
の結果を取得してから、sort を使用します。
"""Query for documents in the collection"""
print("Products with category 'gear-surf-surfboards':\n")
allProductsQuery = {"category": "gear-surf-surfboards"}
for doc in collection.find(allProductsQuery).sort(
"name", pymongo.ASCENDING
):
print("Found a product with _id {}: {}\n".format(doc["_id"], doc))
トラブルシューティング:
The index path corresponding to the specified order-by item is excluded.
などのエラーが発生した場合は、インデックスを作成していることを確認してください。
コードの実行
このアプリでは、MongoDB 用 API データベースとコレクションが作成され、ドキュメントが作成されてから、まったく同じドキュメントが読み戻されます。 この例では、最後に、指定した製品カテゴリと一致するドキュメントを返すクエリが発行されます。 この例では、ステップごとに、実行したステップに関する情報がコンソールに出力されます。
アプリを実行するには、ターミナルを使用してアプリケーション ディレクトリに移動し、アプリケーションを実行します。
python run.py
アプリの出力は次の例のようになります。
Created db 'adventureworks' with shared throughput.
Created collection 'products'.
Indexes are: ['_id_', 'name_1']
Upserted document with _id <ID>
Found a document with _id <ID>:
{'_id': <ID>,
'category': 'gear-surf-surfboards',
'name': 'Yamba Surfboard-50',
'quantity': 1,
'sale': False}
Products with category 'gear-surf-surfboards':
Found a product with _id <ID>:
{'_id': ObjectId('<ID>'),
'name': 'Yamba Surfboard-386',
'category': 'gear-surf-surfboards',
'quantity': 1,
'sale': False}
リソースをクリーンアップする
Azure Cosmos DB for NoSQL アカウントが不要になったら、対応するリソース グループを削除できます。
az group delete
コマンドを使用して、リソース グループを削除します。
az group delete --name $resourceGroupName