本快速入门介绍如何从 Python 应用程序访问 Azure Cosmos DB
API for Table
。 Azure Cosmos DB for Table 是一种无架构数据存储,允许应用程序在云中存储结构化 NoSQL 数据。 由于数据存储在无架构设计中,因此将具有新特性的对象添加到表中时,系统会自动向表中添加新属性(列)。 Python 应用程序可以使用
适用于 Python 的 Azure 数据表 SDK
包访问 Azure Cosmos DB for Table。
示例应用程序是用
Python 3.7 或更高版本
编写的,不过这些原则适用于所有 Python 3.7+ 应用程序。 可以使用
Visual Studio Code
作为 IDE。
如果还没有
Azure 订阅
,可以在开始前创建一个
免费帐户
。
示例应用程序
可以从存储库
https://github.com/Azure-Samples/msdocs-azure-tables-sdk-python-flask
克隆或下载本教程的示例应用程序。
git clone https://github.com/Azure-Samples/msdocs-azure-tables-sdk-python-flask.git
示例存储库中包含 1-starter-app 和 2-completed-app 示例文件夹。 1-starter-app 具有一些功能,可让你完成标记了“#TODO”的行。 本文中显示的代码片段是完成 1-starter-app 的建议附加代码。
已完成的示例应用程序使用天气数据作为示例来演示 API for Table 的功能。 表示天气观察值的对象使用 API for Table 进行存储和检索,其中就包括存储具有额外属性的对象以演示 API for Table 的无架构功能。 下图显示了在浏览器中运行的本地应用程序,其中显示了存储在 Azure Cosmos DB for Table 中的天气数据。
1 - 创建 Azure Cosmos DB 帐户
首先需要创建一个 Azure Cosmos DB Tables API 帐户,该帐户将包含应用程序中使用的表。 使用 Azure 门户、Azure CLI 或 Azure PowerShell 创建帐户。
Azure 门户
Azure CLI
Azure PowerShell
在“创建 Azure Cosmos DB 帐户 - Azure 表”页上填写表单,如下所示。
通过选择“资源组”下的“新建”链接,为名为 rg-msdocs-tables-sdk-demo
的存储帐户创建一个新资源组。
为存储帐户指定名称 cosmos-msdocs-tables-sdk-demo-XYZ
,其中的 XYZ 是三个任意的随机字符,用于创建唯一的帐户名称。 Azure Cosmos DB 帐户名称必须为 3 到 44 个字符长,并且只能包含小写字母、数字或连字符 (-)。
选择存储帐户的区域。
选择“标准”性能。
在“容量模式”下,为此示例选择“预配吞吐量”。
对于此示例,请在“应用免费层折扣”下选择“应用”。
选择屏幕底部的“查看 + 创建”按钮,然后选择摘要屏幕上的“创建”以创建 Azure Cosmos DB 帐户。 此过程可能需要数分钟。
使用 az cosmosdb create 命令来创建 Cosmos DB 帐户。 必须包含 --capabilities EnableTable
选项才能在 Azure Cosmos DB 中启用表存储。 由于所有 Azure 资源必须包含在资源组中,因此以下代码片段还会为 Azure Cosmos DB 帐户创建资源组。
Azure Cosmos DB 帐户名称的长度必须介于 3 到 44 个字符之间,并且只能包含小写字母、数字和连字符 (-) 字符。 此外,Azure Cosmos DB 帐户名称在整个 Azure 中必须唯一。
可以在 Azure Cloud Shell 中或装有 Azure CLI 的工作站上运行 Azure CLI 命令。
Azure Cosmos DB 帐户创建过程通常需要几分钟才能完成。
LOCATION='eastus'
RESOURCE_GROUP_NAME='rg-msdocs-tables-sdk-demo'
COSMOS_ACCOUNT_NAME='cosmos-msdocs-tables-sdk-demo-123' # change 123 to a unique set of characters for a unique name
az group create \
--location $LOCATION \
--name $RESOURCE_GROUP_NAME
az cosmosdb create \
--name $COSMOS_ACCOUNT_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--capabilities EnableTable
Azure Cosmos DB 帐户使用 New-AzCosmosDBAccount cmdlet 来创建。 必须包含 -ApiKind "Table"
选项才能在 Azure Cosmos DB 中启用表存储。 由于所有 Azure 资源必须包含在资源组中,因此以下代码片段还会为 Azure Cosmos DB 帐户创建资源组。
Azure Cosmos DB 帐户名称的长度必须介于 3 到 44 个字符之间,并且只能包含小写字母、数字和连字符 (-) 字符。 Azure Cosmos DB 帐户名称还必须在 Azure 中是唯一的。
Azure PowerShell 命令可以在 Azure Cloud Shell 中或是安装了 Azure PowerShell 的工作站上运行。
Azure Cosmos DB 帐户创建过程通常需要几分钟才能完成。
$location = 'eastus'
$resourceGroupName = 'rg-msdocs-tables-sdk-demo'
$cosmosAccountName = 'cosmos-msdocs-tables-sdk-demo-123' # change 123 to a unique set of characters for a unique name
# Create a resource group
New-AzResourceGroup `
-Location $location `
-Name $resourceGroupName
# Create an Azure Cosmos DB
New-AzCosmosDBAccount `
-Name $cosmosAccountName `
-ResourceGroupName $resourceGroupName `
-Location $location `
-ApiKind "Table"
2 - 创建表
接下来,需要在 Azure Cosmos DB 帐户中创建表,以供应用程序使用。 与传统数据库不同,只需指定表的名称,无需指定表中的属性(列)。 将数据加载到表中时,属性(列)会根据需要自动创建。
Azure 门户
Azure CLI
Azure PowerShell
在Azure 门户,导航到 Azure Cosmos DB 帐户的概述页。
可以通过在顶部搜索栏中键入 Azure Cosmos DB 帐户的名称 (cosmos-msdocs-tables-sdk-demo-XYZ) 并在资源标题下进行查看,导航到 Azure Cosmos DB 帐户的概述页。
选择 Azure Cosmos DB 帐户的名称以转到概述页。
az cosmosdb table create \
--account-name $COSMOS_ACCOUNT_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--name $COSMOS_TABLE_NAME \
--throughput 400
# Create the table for the application to use
New-AzCosmosDBTable `
-Name $cosmosTableName `
-AccountName $cosmosAccountName `
-ResourceGroupName $resourceGroupName
3 - 获取 Azure Cosmos DB 连接字符串
若要访问 Azure Cosmos DB 中的表,你的应用需要 CosmosDB 存储帐户的表连接字符串。 可以使用 Azure 门户、Azure CLI 或 Azure PowerShell 检索该连接字符串。
Azure 门户
Azure CLI
Azure PowerShell
要使用 Azure CLI 获取主连接字符串,请使用 az cosmosdb keys list 命令并指定选项 --type connection-strings
。 此命令使用 JMESPath 查询,以便仅显示主表连接字符串。
# This gets the primary connection string
az cosmosdb keys list \
--type connection-strings \
--resource-group $RESOURCE_GROUP_NAME \
--name $COSMOS_ACCOUNT_NAME \
--query "connectionStrings[?description=='Primary Table Connection String'].connectionString" \
--output tsv
要使用 Azure PowerShell 获取主连接字符串,请使用 Get-AzCosmosDBAccountKey cmdlet。
# This gets the primary connection string
$(Get-AzCosmosDBAccountKey `
-ResourceGroupName $resourceGroupName `
-Name $cosmosAccountName `
-Type "ConnectionStrings")."Primary Table Connection String"
Azure Cosmos DB 帐户的连接字符串被视为应用机密,必须像其他应用机密或密码一样加以保护。
4 - 安装适用于 Python 的 Azure 数据表 SDK
创建 Azure Cosmos DB 帐户后,下一步是安装适用于 Python 的 Microsoft Azure 数据表 SDK。 有关安装该 SDK 的详细信息,请参阅 GitHub 上适用于 Python 的数据表 SDK 存储库中的 README.md 文件。
使用 pip 安装适用于 Python 的 Azure 表客户端库:
pip install azure-data-tables
不要忘记在 1-starter-app 或 2-completed-app 文件夹中安装 requirements.txt。
从 Azure 门户复制你的 Azure Cosmos DB 帐户连接字符串,并使用复制的连接字符串创建 TableServiceClient 对象。 切换到 1-starter-app 或 2-completed-app 文件夹。 无论从哪个应用开始,都需要在 .env
文件中定义环境变量。
# Configuration Parameters
conn_str = "A connection string to an Azure Cosmos DB account."
table_name = "WeatherData"
project_root_path = "Project abs path"
Azure SDK 使用客户端对象与 Azure 通信,以对 Azure 执行不同的操作。 TableServiceClient
对象用于与 Azure Cosmos DB for Table 通信。 应用程序通常只有一个 TableServiceClient
,并且每个表都有一个 TableClient
。
例如,以下代码使用环境变量中的连接字符串创建 TableServiceClient
对象。
self.conn_str = os.getenv("conn_str")
self.table_service = TableServiceClient.from_connection_string(self.conn_str)
6 - 实现 Azure Cosmos DB 表操作
示例应用的所有 Azure Cosmos DB 表操作都在 TableServiceHelper
类中实现,该类位于 webapp 目录下的 helper 文件中。 需要在此文件的顶部导入 TableServiceClient
类才能使用 azure.data.tables Python 客户端库中的对象。
from azure.data.tables import TableServiceClient
在 TableServiceHelper
类的开头,创建一个构造函数并添加用于 TableClient
对象的成员变量,以允许将 TableClient
对象注入该类。
def __init__(self, table_name=None, conn_str=None):
self.table_name = table_name if table_name else os.getenv("table_name")
self.conn_str = conn_str if conn_str else os.getenv("conn_str")
self.table_service = TableServiceClient.from_connection_string(self.conn_str)
self.table_client = self.table_service.get_table_client(self.table_name)
筛选从表返回的行
若要筛选从表返回的行,可以将 OData 样式筛选器字符串传递到 query_entities
方法。 例如,如果要获取 2021 年 7 月 1 日午夜到 2021 年 7 月 2 日午夜(含)之间的所有芝加哥天气读数,则传入以下筛选器字符串。
PartitionKey eq 'Chicago' and RowKey ge '2021-07-01 12:00 AM' and RowKey le '2021-07-02 12:00 AM'
你可以在编写筛选器部分的 azure-data-tables 网站中查看相关的 OData 筛选器运算符。
将 request.args 参数传递到 TableServiceHelper
类中的 query_entity
方法时,它会为每个非 null 属性值创建一个筛选器字符串。 它随后会使用“and”子句将所有值联接在一起,以创建合并筛选器字符串。 此合并筛选器字符串会传递到 TableClient
对象上的 query_entities
方法,仅返回与筛选器字符串匹配的行。 可以在代码中使用类似方法,根据应用程序的要求构造合适的筛选器字符串。
def query_entity(self, params):
filters = []
if params.get("partitionKey"):
filters.append("PartitionKey eq '{}'".format(params.get("partitionKey")))
if params.get("rowKeyDateStart") and params.get("rowKeyTimeStart"):
filters.append("RowKey ge '{} {}'".format(params.get("rowKeyDateStart"), params.get("rowKeyTimeStart")))
if params.get("rowKeyDateEnd") and params.get("rowKeyTimeEnd"):
filters.append("RowKey le '{} {}'".format(params.get("rowKeyDateEnd"), params.get("rowKeyTimeEnd")))
if params.get("minTemperature"):
filters.append("Temperature ge {}".format(params.get("minTemperature")))
if params.get("maxTemperature"):
filters.append("Temperature le {}".format(params.get("maxTemperature")))
if params.get("minPrecipitation"):
filters.append("Precipitation ge {}".format(params.get("minPrecipitation")))
if params.get("maxPrecipitation"):
filters.append("Precipitation le {}".format(params.get("maxPrecipitation")))
return list(self.table_client.query_entities(" and ".join(filters)))
使用 TableEntity 对象插入数据
将数据添加到表的最简单方法是使用 TableEntity
对象。 在此示例中,数据会从输入模型对象映射到 TableEntity
对象。 输入对象中表示气象站名称和观察日期/时间的属性分别映射到 PartitionKey
和 RowKey
属性,这些属性共同构成表中行的唯一键。 输入模型对象上的额外属性随后会映射到 TableEntity 对象上的字典属性。 最后,TableClient
对象上的 create_entity
方法用于将数据插入表中。
修改示例应用程序中的 insert_entity
函数,以包含以下代码。
def insert_entity(self):
entity = self.deserialize()
return self.table_client.create_entity(entity)
@staticmethod
def deserialize():
params = {key: request.form.get(key) for key in request.form.keys()}
params["PartitionKey"] = params.pop("StationName")
params["RowKey"] = "{} {}".format(params.pop("ObservationDate"), params.pop("ObservationTime"))
return params
使用 TableEntity 对象更新插入数据
如果尝试向表中插入的行具有该表中已存在的分区键/行键组合,则会收到错误。 因此,在向表添加行时,通常最好使用 upsert_entity
而不是 create_entity
方法。 如果表中已存在给定分区键/行键组合,则 upsert_entity
方法会更新现有行。 否则,行会添加到表中。
def upsert_entity(self):
entity = self.deserialize()
return self.table_client.upsert_entity(entity)
@staticmethod
def deserialize():
params = {key: request.form.get(key) for key in request.form.keys()}
params["PartitionKey"] = params.pop("StationName")
params["RowKey"] = "{} {}".format(params.pop("ObservationDate"), params.pop("ObservationTime"))
return params
使用变量属性插入或更新插入数据
使用 Azure Cosmos DB for Table 的一个好处是,如果要加载到表的对象包含任何新属性,那这些属性会自动添加到表中并且值存储在 Azure Cosmos DB 中。 无需如同传统数据库中一样,运行 ALTER TABLE 等 DDL 语句来添加列。
在处理可能会随着时间推移添加或修改需要捕获的数据的数据源时,或者在不同的输入向应用程序提供不同的数据时,此模型可使应用程序具有灵活性。 在示例应用程序中,我们可以模拟一个不仅发送基本天气数据,而且还发送一些额外值的气象站。 首次将具有这些新属性的对象存储在表中时,对应属性(列)会自动添加到表中。
若要使用 API for Table 插入或更新插入此类对象,请将可扩充对象的属性映射到 TableEntity
对象,并根据需要对 TableClient
对象使用 upsert_entity
或 create_entity
方法。
在示例应用程序中,upsert_entity
函数还可实现使用变量属性插入或更新插入数据的功能
def insert_entity(self):
entity = self.deserialize()
return self.table_client.create_entity(entity)
def upsert_entity(self):
entity = self.deserialize()
return self.table_client.upsert_entity(entity)
@staticmethod
def deserialize():
params = {key: request.form.get(key) for key in request.form.keys()}
params["PartitionKey"] = params.pop("StationName")
params["RowKey"] = "{} {}".format(params.pop("ObservationDate"), params.pop("ObservationTime"))
return params
可以通过对 TableClient
对象调用 update_entity
方法来更新实体。
在示例应用中,此对象会传递到 TableClient
类中的 upsert_entity
方法。 它更新该实体对象,并使用 upsert_entity
方法将更新保存到数据库。
def update_entity(self):
entity = self.update_deserialize()
return self.table_client.update_entity(entity)
@staticmethod
def update_deserialize():
params = {key: request.form.get(key) for key in request.form.keys()}
params["PartitionKey"] = params.pop("StationName")
params["RowKey"] = params.pop("ObservationDate")
return params
若要从表中删除实体,请使用对象的分区键和行键对 TableClient
对象调用 delete_entity
方法。
def delete_entity(self):
partition_key = request.form.get("StationName")
row_key = request.form.get("ObservationDate")
return self.table_client.delete_entity(partition_key, row_key)
7 - 运行代码
运行示例应用程序以与 Azure Cosmos DB for Table 交互。 例如,从 2-completed-app 文件夹开始,安装了要求项后,可以使用:
python3 run.py webapp
有关运行示例应用程序的详细信息,请参阅示例存储库根路径中的 README.md 文件。
首次运行应用程序时没有数据,因为表为空。 使用应用程序顶部的任何按钮将数据添加到表。
选择“使用表实体插入”按钮会打开一个对话框,使你可以使用 TableEntity
对象插入或更新插入新行。
选择“使用可扩展数据插入”按钮后,将会打开一个对话框,在其中可以插入具有自定义属性的对象,并演示 Azure Cosmos DB for Table 如何根据需要自动将属性(列)添加到表中。 使用“添加自定义字段”按钮添加一个或多个新属性并演示此功能。
使用“插入示例数据”按钮将一些示例数据加载到 Azure Cosmos DB 表中。
对于 1-starter-app 示例文件夹,至少需要完成 submit_transaction
函数的代码,才能使示例数据插入正常工作。
示例数据从 sample_data.json 文件加载。 .env 变量 project_root_path
告知应用在何处查找此文件。 例如,如果从 1-starter-app 或 2-completed-app 文件夹运行应用程序,请将 project_root_path
设置为“”(空白)。
若要使用 Azure CLI 删除资源组,请结合要删除的资源组的名称使用 az group delete 命令。 删除某个资源组后,还会删除该资源组中包含的所有 Azure 资源。
az group delete --name $RESOURCE_GROUP_NAME
若要使用 Azure PowerShell 删除资源组,请结合要删除的资源组的名称使用 Remove-AzResourceGroup 命令。 删除某个资源组后,还会删除该资源组中包含的所有 Azure 资源。
Remove-AzResourceGroup -Name $resourceGroupName
在本快速入门教程中,已了解如何创建 Azure Cosmos DB 帐户、使用数据资源管理器创建表和运行应用。 现在可以使用 API for Table 进行数据查询了。
使用 API for Table 查询 Azure Cosmos DB