選項
首頁首頁 Skill 資料庫管理 azure-cosmos-py

azure-cosmos-py

microsoft/skills microsoft/skills

使用 Python SDK 在 Azure Cosmos DB NoSQL API 上執行 CRUD 操作、執行查詢以及管理容器。

...展開全部
12
更新時間 2026-09-12

Azure Cosmos DB Python SDK

Azure Cosmos DB NoSQL API 的客戶端函式庫 — 全球分散式、多模型資料庫。

安裝

pip install azure-cosmos azure-identity

環境變數

COSMOS_ENDPOINT=https://.documents.azure.com:443/  # 所有驗證方法皆需設定
COSMOS_DATABASE=mydb  # 所有驗證方法皆需設定
COSMOS_CONTAINER=mycontainer  # 所有驗證方法皆需設定
AZURE_TOKEN_CREDENTIALS=prod # 僅當在生產環境中使用 DefaultAzureCredential 時才需設定

驗證與生命週期

🔑 以下每個程式碼範例均適用兩項規則:

  1. 優先使用DefaultAzureCredential它可在本地端(Azure CLI / VS Code / Developer CLI)及 Azure 環境(託管身分識別、工作負載身分識別)中運作,且無需修改程式碼。請避免使用連線字串、帳戶/API 金鑰——這些會繞過 Entra 稽核與輪替機制。
    • 本地開發:DefaultAzureCredential可直接使用。
    • 生產環境:請設定AZURE_TOKEN_CREDENTIALS=prod(或AZURE_TOKEN_CREDENTIALS= ),以將憑證鏈限制為符合生產環境安全標準的憑證。
  2. 將每個客戶端封裝在上下文管理器中,以確保 HTTP 傳輸、套接字和憑證快取能以確定性方式釋放:
    • 同步模式:使用 `(...) as client:`
    • 非同步:使用 `(...)` 作為 `client` 的 `async` ,以及使用 `DefaultAzureCredential()` 作為 `credential` 的 `async`:(來自azure.identity.aio

程式碼片段可能會簡化此設定,但生產環境的程式碼應始終遵循這兩項規則。

import os
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential
from azure.cosmos import CosmosClient

# 本地開發:使用 DefaultAzureCredential。生產環境:設定 AZURE_TOKEN_CREDENTIALS=prod 或 AZURE_TOKEN_CREDENTIALS=
credential = DefaultAzureCredential(require_envvar=True)
# 或者在生產環境中直接使用特定憑證:
# 請參閱 https://learn.microsoft.com/python/api/overview/azure/identity-readme?view=azure-python#credential-classes
# credential = ManagedIdentityCredential()

endpoint = "https://.documents.azure.com:443/"

with CosmosClient(url=endpoint, credential=credential) as client:
    # 在此處使用該客戶端(操作詳情請參閱後續章節)
    ...

客戶端層級結構

Client 用途 取自
CosmosClient 帳戶層級操作 直接實例化
DatabaseProxy 資料庫操作 client.get_database_client()
ContainerProxy 容器/項目操作 database.get_container_client()

核心工作流程

設定資料庫與容器

# 取得或建立資料庫
database = client.create_database_if_not_exists(id="mydb")

# 根據分區鍵取得或建立容器
container = database.create_container_if_not_exists(
    id="mycontainer",
    partition_key=PartitionKey(path="/category")
)

# 取得現有資料
database = client.get_database_client("mydb")
container = database.get_container_client("mycontainer")

建立項目

item = {
    "id": "item-001",           # 必填:在分區內必須唯一
    "category": "electronics",   # 分區鍵值
    "name": "Laptop",
    "price": 999.99,
    "tags": ["computer", "portable"]
}

created = container.create_item(body=item)
print(f"已建立:{created['id']}")

讀取項目

# 讀取需同時提供 id 與分區鍵
item = container.read_item(
    item="item-001",
    partition_key="electronics"
)
print(f"名稱:{item['name']}")

更新項目(覆寫)

item = container.read_item(item="item-001", partition_key="electronics")
item["price"] = 899.99
item["on_sale"] = True

updated = container.replace_item(item=item["id"], body=item)

Upsert 項目

# 若不存在則建立,若存在則替換
item = {
    "id": "item-002",
    "category": "electronics",
    "name": "平板電腦",
    "price": 499.99
}

result = container.upsert_item(body=item)

刪除項目

container.delete_item(
    item="item-001",
    partition_key="electronics"
)

查詢

基本查詢

# 在分區內查詢 (高效)
query = "SELECT * FROM c WHERE c.price < @max_price"
items = container.query_items(
    query=query,
    parameters=[{"name": "@max_price", "value": 500}],
    partition_key="electronics"
)

for item in items:
    print(f"{item['name']}: ${item['price']}")
</code></pre>
<h3>跨分區查詢</h3>
<pre><code class="language-python"># 跨分區(成本較高,請謹慎使用)
query = "SELECT * FROM c WHERE c.price < @max_price"
items = container.query_items(
    query=query,
    parameters=[{"name": "@max_price", "value": 500}],
    enable_cross_partition_query=True
)

for item in items:
    print(item)
</code></pre>
<h3>帶投影的查詢</h3>
<pre><code class="language-python">query = "SELECT c.id, c.name, c.price FROM c WHERE c.category = @category"
items = container.query_items(
    query=query,
    parameters=[{"name": "@category", "value": "electronics"}],
    partition_key="electronics"
)
</code></pre>
<h3>讀取所有項目</h3>
<pre><code class="language-python"># 讀取分區中的所有項目
items = container.read_all_items()  # 跨分區
# 或使用分區鍵
items = container.query_items(
    query="SELECT * FROM c",
    partition_key="electronics"
)
</code></pre>
<h2>分區鍵</h2>
<p><strong>重要</strong>:為確保操作效率,請務必包含分區鍵。</p>
<pre><code class="language-python">from azure.cosmos import PartitionKey

# 單一分區鍵
container = database.create_container_if_not_exists(
    id="orders",
    partition_key=PartitionKey(path="/customer_id")
)

# 階層式分區金鑰(預覽版)
container = database.create_container_if_not_exists(
    id="events",
    partition_key=PartitionKey(path=["/tenant_id", "/user_id"])
)
</code></pre>
<h2>吞吐量</h2>
<pre><code class="language-python"># 建立具有預配置吞吐量的容器
container = database.create_container_if_not_exists(
    id="mycontainer",
    partition_key=PartitionKey(path="/pk"),
    offer_throughput=400  # RU/s
)

# 讀取當前吞吐量
offer = container.read_offer()
print(f"吞吐量:{offer.offer_throughput} RU/s")

# 更新吞吐量
container.replace_throughput(throughput=1000)
</code></pre>
<h2>非同步客戶端</h2>
<pre><code class="language-python">from azure.cosmos.aio import CosmosClient
from azure.identity.aio import DefaultAzureCredential

async def cosmos_operations():
    async with DefaultAzureCredential() as credential:
        async with CosmosClient(endpoint, credential=credential) as client:
            database = client.get_database_client("mydb")
            container = database.get_container_client("mycontainer")
            
            # 建立
            await container.create_item(body={"id": "1", "pk": "test"})
            
            # 讀取
            item = await container.read_item(item="1", partition_key="test")
            
            # 查詢
            async for item in container.query_items(
                query="SELECT * FROM c",
                partition_key="test"
            ):
                print(item)

import asyncio
asyncio.run(cosmos_operations())
</code></pre>
<h2>錯誤處理</h2>
<pre><code class="language-python">from azure.cosmos.exceptions import CosmosHttpResponseError

try:
    item = container.read_item(item="nonexistent", partition_key="pk")
except CosmosHttpResponseError as e:
    if e.status_code == 404:
        print("未找到項目")
    elif e.status_code == 429:
        print(f"速率限制。 請於 {e.headers.get('x-ms-retry-after-ms')} 毫秒後重試")
    else:
        raise
</code></pre>
<h2>最佳實務</h2>
<ol>
<li><strong>選擇同步或非同步模式,並保持一致性。</strong> 請勿在同一個呼叫路徑中混合使用 <code>azure.cosmos</code> 同步客戶端與 <code>azure.cosmos.aio</code> 非同步客戶端。每個模組應選擇一種模式。</li>
<li><strong>請務必為客戶端和非同步憑證使用上下文管理器。</strong> 將每個客戶端封裝在 <code>with CosmosClient(...) as client:</code>(同步)或 <code>async with CosmosClient(...) as client:</code>(非同步)中。 對於來自 <code>azure.identity.aio</code> 的非同步 <code>DefaultAzureCredential</code>,也請使用 <code>async with credential:</code>,以確保代幣和傳輸資料能被妥善清理。</li>
<li><strong>請使用 <code>DefaultAzureCredential</code></strong> 實現本地開發環境與 Azure 之間的可攜式驗證(盡可能避免使用連線字串/API 金鑰)。</li>
<li><strong>針對點讀取和查詢,請務必指定分區金鑰</strong></li>
<li><strong>使用參數化查詢</strong> 以防止注入攻擊並改善快取效能</li>
<li><strong>盡可能避免跨分區查詢</strong></li>
<li><strong>使用 <code>upsert_item</code></strong> 進行冪等寫入</li>
<li><strong>在高吞吐量情境下,請使用 </strong> 非同步客戶端</li>
<li><strong>設計分區鍵</strong> 以實現均勻的資料分佈</li>
<li><strong>檢索單一文件時,請使用 <code>read_item</code></strong> 取代查詢</li>
</ol>
<h2>參考檔案</h2>
<table>
<thead>
<tr>
<th>檔案</th>
<th>內容</th>
</tr>
</thead>
<tbody><tr>
<td>references/partitioning.md</td>
<td>分區鍵策略、層級鍵、熱分區偵測與緩解措施</td>
</tr>
<tr>
<td>references/query-patterns.md</td>
<td>查詢優化、聚合、分頁、交易、變更饋送</td>
</tr>
<tr>
<td>scripts/setup_cosmos_container.py</td>
<td>用於建立具備分區、吞吐量及索引功能的容器的 CLI 工具</td>
</tr>
</tbody></table>                                
在 GitHub 上查看
---
name: azure-cosmos-py
description: Perform CRUD operations, run queries, and manage containers on Azure Cosmos DB NoSQL API using the Python SDK.
license: MIT
---

# Azure Cosmos DB SDK for Python

Client library for Azure Cosmos DB NoSQL API — globally distributed, multi-model database.

## Installation

```bash
pip install azure-cosmos azure-identity
```

## Environment Variables

```bash
COSMOS_ENDPOINT=https://<account>.documents.azure.com:443/  # Required for all auth methods
COSMOS_DATABASE=mydb  # Required for all auth methods
COSMOS_CONTAINER=mycontainer  # Required for all auth methods
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production
```

## Authentication & Lifecycle

> **🔑 Two rules apply to every code sample below:**
>
> 1. **Prefer `DefaultAzureCredential`.** It works locally (Azure CLI / VS Code / Developer CLI) and in Azure (managed identity, workload identity) with no code change. Avoid connection strings, account/API keys — they bypass Entra audit and rotation.
>    - Local dev: `DefaultAzureCredential` works as-is.
>    - Production: set `AZURE_TOKEN_CREDENTIALS=prod` (or `AZURE_TOKEN_CREDENTIALS=<specific_credential>`) to constrain the credential chain to production-safe credentials.
> 2. **Wrap every client in a context manager** so HTTP transports, sockets, and token caches are released deterministically:
>    - Sync: `with <Client>(...) as client:`
>    - Async: `async with <Client>(...) as client:` **and** `async with DefaultAzureCredential() as credential:` (from `azure.identity.aio`)
>
> Snippets may abbreviate this setup, but production code should always follow both rules.

```python
import os
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential
from azure.cosmos import CosmosClient

# Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
credential = DefaultAzureCredential(require_envvar=True)
# Or use a specific credential directly in production:
# See https://learn.microsoft.com/python/api/overview/azure/identity-readme?view=azure-python#credential-classes
# credential = ManagedIdentityCredential()

endpoint = "https://<account>.documents.azure.com:443/"

with CosmosClient(url=endpoint, credential=credential) as client:
    # Use client here (see following sections for operations)
    ...
```

## Client Hierarchy

| Client | Purpose | Get From |
|--------|---------|----------|
| `CosmosClient` | Account-level operations | Direct instantiation |
| `DatabaseProxy` | Database operations | `client.get_database_client()` |
| `ContainerProxy` | Container/item operations | `database.get_container_client()` |

## Core Workflow

### Setup Database and Container

```python
# Get or create database
database = client.create_database_if_not_exists(id="mydb")

# Get or create container with partition key
container = database.create_container_if_not_exists(
    id="mycontainer",
    partition_key=PartitionKey(path="/category")
)

# Get existing
database = client.get_database_client("mydb")
container = database.get_container_client("mycontainer")
```

### Create Item

```python
item = {
    "id": "item-001",           # Required: unique within partition
    "category": "electronics",   # Partition key value
    "name": "Laptop",
    "price": 999.99,
    "tags": ["computer", "portable"]
}

created = container.create_item(body=item)
print(f"Created: {created['id']}")
```

### Read Item

```python
# Read requires id AND partition key
item = container.read_item(
    item="item-001",
    partition_key="electronics"
)
print(f"Name: {item['name']}")
```

### Update Item (Replace)

```python
item = container.read_item(item="item-001", partition_key="electronics")
item["price"] = 899.99
item["on_sale"] = True

updated = container.replace_item(item=item["id"], body=item)
```

### Upsert Item

```python
# Create if not exists, replace if exists
item = {
    "id": "item-002",
    "category": "electronics",
    "name": "Tablet",
    "price": 499.99
}

result = container.upsert_item(body=item)
```

### Delete Item

```python
container.delete_item(
    item="item-001",
    partition_key="electronics"
)
```

## Queries

### Basic Query

```python
# Query within a partition (efficient)
query = "SELECT * FROM c WHERE c.price < @max_price"
items = container.query_items(
    query=query,
    parameters=[{"name": "@max_price", "value": 500}],
    partition_key="electronics"
)

for item in items:
    print(f"{item['name']}: ${item['price']}")
```

### Cross-Partition Query

```python
# Cross-partition (more expensive, use sparingly)
query = "SELECT * FROM c WHERE c.price < @max_price"
items = container.query_items(
    query=query,
    parameters=[{"name": "@max_price", "value": 500}],
    enable_cross_partition_query=True
)

for item in items:
    print(item)
```

### Query with Projection

```python
query = "SELECT c.id, c.name, c.price FROM c WHERE c.category = @category"
items = container.query_items(
    query=query,
    parameters=[{"name": "@category", "value": "electronics"}],
    partition_key="electronics"
)
```

### Read All Items

```python
# Read all in a partition
items = container.read_all_items()  # Cross-partition
# Or with partition key
items = container.query_items(
    query="SELECT * FROM c",
    partition_key="electronics"
)
```

## Partition Keys

**Critical**: Always include partition key for efficient operations.

```python
from azure.cosmos import PartitionKey

# Single partition key
container = database.create_container_if_not_exists(
    id="orders",
    partition_key=PartitionKey(path="/customer_id")
)

# Hierarchical partition key (preview)
container = database.create_container_if_not_exists(
    id="events",
    partition_key=PartitionKey(path=["/tenant_id", "/user_id"])
)
```

## Throughput

```python
# Create container with provisioned throughput
container = database.create_container_if_not_exists(
    id="mycontainer",
    partition_key=PartitionKey(path="/pk"),
    offer_throughput=400  # RU/s
)

# Read current throughput
offer = container.read_offer()
print(f"Throughput: {offer.offer_throughput} RU/s")

# Update throughput
container.replace_throughput(throughput=1000)
```

## Async Client

```python
from azure.cosmos.aio import CosmosClient
from azure.identity.aio import DefaultAzureCredential

async def cosmos_operations():
    async with DefaultAzureCredential() as credential:
        async with CosmosClient(endpoint, credential=credential) as client:
            database = client.get_database_client("mydb")
            container = database.get_container_client("mycontainer")
            
            # Create
            await container.create_item(body={"id": "1", "pk": "test"})
            
            # Read
            item = await container.read_item(item="1", partition_key="test")
            
            # Query
            async for item in container.query_items(
                query="SELECT * FROM c",
                partition_key="test"
            ):
                print(item)

import asyncio
asyncio.run(cosmos_operations())
```

## Error Handling

```python
from azure.cosmos.exceptions import CosmosHttpResponseError

try:
    item = container.read_item(item="nonexistent", partition_key="pk")
except CosmosHttpResponseError as e:
    if e.status_code == 404:
        print("Item not found")
    elif e.status_code == 429:
        print(f"Rate limited. Retry after: {e.headers.get('x-ms-retry-after-ms')}ms")
    else:
        raise
```

## Best Practices

1. **Pick sync OR async and stay consistent.** Do not mix `azure.cosmos` sync clients with `azure.cosmos.aio` async clients in the same call path. Choose one mode per module.
2. **Always use context managers for clients and async credentials.** Wrap every client in `with CosmosClient(...) as client:` (sync) or `async with CosmosClient(...) as client:` (async). For async `DefaultAzureCredential` from `azure.identity.aio`, also use `async with credential:` so tokens and transports are cleaned up.
3. **Use `DefaultAzureCredential`** for portable auth across local dev and Azure (avoid connection strings / API keys when possible).
4. **Always specify partition key** for point reads and queries
5. **Use parameterized queries** to prevent injection and improve caching
6. **Avoid cross-partition queries** when possible
7. **Use `upsert_item`** for idempotent writes
8. **Use async client** for high-throughput scenarios
9. **Design partition key** for even data distribution
10. **Use `read_item`** instead of query for single document retrieval

## Reference Files

| File | Contents |
|------|----------|
| [references/partitioning.md](references/partitioning.md) | Partition key strategies, hierarchical keys, hot partition detection and mitigation |
| [references/query-patterns.md](references/query-patterns.md) | Query optimization, aggregations, pagination, transactions, change feed |
| [scripts/setup_cosmos_container.py](scripts/setup_cosmos_container.py) | CLI tool for creating containers with partitioning, throughput, and indexing |

所有檔案

0 個檔案

安裝 azure-cosmos-py

請下載並將技能檔案解壓縮至您的 .claude/skills/ 目錄中。

下載 ZIP

複製儲存庫並將技能檔案複製到您的專案中。

git clone https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-python/skills/azure-cosmos-py # Copy SKILL.md to your .claude/skills/ directory

複製 複製
快速設定: 將技能資料夾複製到 .claude/skills/ Claude 會自動偵測並使用該技能
儲存庫 microsoft/skills

相關技能

microservices-patterns
更新時間 2026-06-29
jpa-patterns
更新時間 2026-06-30
fabric-lakehouse
更新時間 2026-06-30
prisma-expert
更新時間 2026-06-29