クイックスタート: MongoDB ドライバーを使用する Python 用 Azure Cosmos DB for MongoDB

適用対象: MongoDB

MongoDB の使用を開始して、Azure Cosmos DB リソース内にデータベース、コレクション、ドキュメントを作成します。 Azure Developer CLI を使って最小限のソリューションを環境にデプロイするには、以下の手順に従います。

MongoDB 用 API リファレンス ドキュメント | pymongo パッケージ | Azure Developer CLI

前提条件

設定

このプロジェクトの開発コンテナーをお使いの環境にデプロイします。 次に、Azure Developer CLI (azd) を使って、Azure Cosmos DB for MongoDB アカウントを作成し、コンテナー化されたサンプル アプリケーションをデプロイします。 サンプル アプリケーションでは、クライアント ライブラリを使って、サンプル データの管理、作成、読み取り、クエリを実行します。

GitHub codespaces で開く

開発コンテナーで開く

重要

GitHub アカウントには、ストレージとコア時間のエンタイトルメントが無料で含まれています。 詳細については、GitHub アカウントに含まれるストレージとコア時間に関する記事を参照してください。

  1. プロジェクトのルート ディレクトリでターミナルを開きます。

  2. azd auth login を使って Azure Developer CLI に対して認証します。 ツールによって指示された手順に従って、任意の Azure 資格情報を使って CLI に対して認証します。

    azd auth login
    
  3. azd init を使ってプロジェクトを初期化します。

    azd init --template cosmos-db-mongodb-python-quickstart
    

    Note

    このクイックスタートでは、azure-samples/cosmos-db-mongodb-python-quickstart テンプレートの GitHub リポジトリを使用します。 このプロジェクトがまだお使いのマシンにない場合は、Azure Developer CLI によって自動的にクローンされます。

  4. 初期化中に、一意の環境名を構成します。

    ヒント

    この環境名は、ターゲット リソース グループ名としても使用されます。 このクイックスタートでは、msdocs-cosmos-db の使用を検討してください。

  5. azd up を使って、Azure Cosmos DB アカウントをデプロイします。 Bicep テンプレートは、サンプル Web アプリケーションもデプロイします。

    azd up
    
  6. プロビジョニング プロセス中に、サブスクリプションと目的の場所を選択します。 プロビジョニング プロセスが完了するまで待ちます。 このプロセスには 5 分ほどかかる可能性があります。

  7. Azure リソースのプロビジョニングが完了すると、実行中の Web アプリケーションへの URL が出力に含まれます。

    Deploying services (azd deploy)
    
      (✓) Done: Deploying service web
    - Endpoint: <https://[container-app-sub-domain].azurecontainerapps.io>
    
    SUCCESS: Your application was provisioned and deployed to Azure in 5 minutes 0 seconds.
    
  8. コンソールで URL を使って、ブラウザーで Web アプリケーションに移動します。 実行中のアプリの出力を確認します。

    実行中の Web アプリケーションのスクリーンショット。


クライアント ライブラリをインストールする

  1. PyMongopython-dotenv パッケージの一覧が記載された、requirements.txt ファイルをアプリ ディレクトリに作成します。

    # requirements.txt
    pymongo
    python-dotenv
    
  2. 仮想環境を作成し、パッケージをインストールします。

    # 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
    

オブジェクト モデル

MongoDB 用 API のリソースの階層と、これらのリソースの作成とアクセスに使用されるオブジェクト モデルについて説明します。 Azure Cosmos DB によって、アカウント、データベース、コレクション、ドキュメントで構成される階層内にリソースが作成されます。

アカウント、データベース、コレクション、ドキュメントを含む 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 ドライバーを使用します。

クライアントを認証する

  1. プロジェクト ディレクトリで、run.py ファイルを作成します。 使用するパッケージ (PyMongo パッケージや python-dotenv パッケージなど) を参照するために、エディターで require ステートメントを追加します。

    import os
    import sys
    from random import randint
    
    import pymongo
    from dotenv import load_dotenv
    
  2. .env ファイルで定義されている環境変数から接続情報を取得します。

    load_dotenv()
    CONNECTION_STRING = os.environ.get("COSMOS_CONNECTION_STRING")
    
  3. コードで使用する定数を定義します。

    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