python + Azure Cosmos DB (非常规方法)

1.作为一个数据库服务,使用之前需要一个数据库的账户。
这个账户可以在portal上做成,叫做Azure Cosmos DB Account
下面这张官网上的图片很好的反应了Azure Cosmos DB 的逻辑结构

python + Azure Cosmos DB

一个Azure Cosmos DB Account下面可以有很多个database,
database有点像一个namesapce,他可以包含多个container
而数据是存放在container里面的。

2.python访问Azure Cosmos DB,必须先有一个CosmosClient class。
它负责执行所有的request。然后才能创建database,container等等。
实例化这个class的方式有2种:
①Azure Cosmos DB Account 和 its primary master key 。
②用AAD credentials 和 the azure identity package
使用AAD credentials 的话,需要在azure 上注册一个app。详细的步骤可以参考下面的链接。
Authenticate to Azure resources from Python apps hosted on-premises | Microsoft Learn

官方推荐用the azure identity package,所以今天来研究这种方式

import os
from azure.cosmos import CosmosClient,exceptions
from azure.identity import DefaultAzureCredential
#创建环境变量
endpoint=os.environ["COSMOS_ENDPOINT"]
#create cosmosclient
credential = DefaultAzureCredential()
client=CosmosClient(url=endpoint,credential=credential)
#
#定义数据库名称,容器名称
#DATABASE_NAME = "cosmicwork"
CONTAINER_NAME = "products"
DATABASE_NAME = "database001"
#create databases
try:
    database=client.create_database(DATABASE_NAME)
except exceptions.CosmosResourceExistsError:
    database=client.get_database_client(DATABASE_NAME)

注意:事先需要设置环境变量COSMOS_ENDPOINT
需要用Azure CLI来执行

$env:COSMOS_ENDPOINT = "<cosmos-account-URI>"

报错了

Traceback (most recent call last):
  File "C:\xxxxxx\Dev\cosmosDB.py", line 16, in <module>
    database=client.create_database(DATABASE_NAME)
  File "xxxxxxxxxxxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\core\tracing\decorator.py", line 76, in wrapper_use_tracer
    return func(*args, **kwargs)
  File "xxxxxxxxxxxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\cosmos\cosmos_client.py", line 280, in create_database
    result = self.client_connection.CreateDatabase(database=dict(id=id), options=request_options, **kwargs)
  File "xxxxxxxxxxxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\cosmos\_cosmos_client_connection.py", line 322, in CreateDatabase
    return self.Create(database, path, "dbs", None, None, options, **kwargs)
  File "xxxxxxxxxxxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\cosmos\_cosmos_client_connection.py", line 2176, in Create
    result, self.last_response_headers = self.__Post(path, request_params, body, headers, **kwargs)
  File "xxxxxxxxxxxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\cosmos\_cosmos_client_connection.py", line 2342, in __Post
    return synchronized_request.SynchronizedRequest(
  File "xxxxxxxxxxxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\cosmos\_synchronized_request.py", line 206, in SynchronizedRequest
    return _retry_utility.Execute(
  File "xxxxxxxxxxxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\cosmos\_retry_utility.py", line 83, in Execute  
    result = ExecuteFunction(function, global_endpoint_manager, *args, **kwargs)
  File "xxxxxxxxxxxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\cosmos\_retry_utility.py", line 143, in ExecuteFunction
    return function(*args, **kwargs)
  File "xxxxxxxxxxxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\cosmos\_synchronized_request.py", line 154, in _Request
    raise exceptions.CosmosHttpResponseError(message=data, response=response)
azure.cosmos.exceptions.CosmosHttpResponseError: (Forbidden) Request blocked by Auth xxxxxxcosmosdb : The given request [POST /dbs] cannot be authorized by AAD token in data plane. Learn more: https://aka.ms/cosmos-native-rbac.
ActivityId: 1753a765-b224-474b-a2ec-607c7f2897e3, Microsoft.Azure.Documents.Common/2.14.0
Code: Forbidden
Message: Request blocked by Auth xxxxxxcosmosdb : The given request [POST /dbs] cannot be authorized by AAD token in data plane. Learn more: https://aka.ms/cosmos-native-rbac.
ActivityId: aaaaaaaaaaaaaa, Microsoft.Azure.Documents.Common/2.14.0

看起来像是权限问题,查了好久。
这里用到的是DefaultAzureCredential这个class。他是怎么认证request的呢?
关于认证,
运行在on-premises 和运行在Azure的Python apps ,认证方式也是不同的。

python + Azure Cosmos DB
DefaultAzureCredential支持多种认证方式,
比如这个例子,本地开发时,使用Azure cli的方式登录到azure,
deploy 到azure上以后使用同一个账户。
无论哪种方式,本地开发的user account,需要被正确配置RBAC。

那么先做一个role,然后再把role赋给本地vscode执行az login时登录的用户。
①创建role

az cosmosdb sql role definition create \
    --account-name <cosmosdb-account-name> \
    --resource-group  <resource-group-name> \
    --body '{
    "RoleName": "PasswordlessReadWrite",
    "Type": "CustomRole",
    "AssignableScopes": ["/"],
    "Permissions": [{
        "DataActions": [
            "Microsoft.DocumentDB/databaseAccounts/readMetadata",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
        ]
    }]
}'

②把role 付给用户

az cosmosdb sql role assignment create \
    --account-name <cosmosdb-account-name> \
    --resource-group  <resource-group-name> \
    --scope "/" \
    --principal-id <your-user-id> \
    --role-definition-id <your-custom-role-id>

依然不能行噢噢噢噢

从下面这个资料来看,像是不能用?
Quickstart - Azure Cosmos DB for NoSQL client library for Python | Microsoft Learn

python + Azure Cosmos DB

改用Azure CLI来创建databease

# Create a SQL API database `
az cosmosdb sql database create `
    --account-name <cosmos-db-account-name> `
    --resource-group <resource-group-name> `
    --name cosmicworks

创建成功了。

3.有了database,现在就可创建container了

# Create a SQL API container
az cosmosdb sql container create `
    --account-name <cosmos-db-account-name> `
    --resource-group <resource-group-name> `
    --database-name cosmicworks `
    --partition-key-path "/categoryId" `
    --name products

4.最后一步,就是插入数据啦

for i in range(1, 10):
    container.upsert_item({
            'id': 'item{0}'.format(i),
            'productName': 'Widget',
            'productModel': 'Model {0}'.format(i)
        }
    )

参考资料:
Disclaimer — Azure SDK for Python 2.0.0 documentation (windows.net)
Quickstart - Azure Cosmos DB for NoSQL client library for Python | Microsoft Learn
Overview: Authenticate Python apps to Azure using the Azure SDK | Microsoft Learn

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!