快速入門:使用 Python SDK 與 Azure Cosmos DB 建置 API for Table 應用程式

適用於: Table

本快速入門說明如何從 Python 應用程式存取 Azure Cosmos DB 資料表 API。 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-app2-completed-app 範例資料夾。 1-starter-app 有一些功能留待您以標示為"#TODO" 的指令行完成。 本文中顯示的程式碼片段是完成 1-starter-app 的建議附加程式碼。

已完成的應用程式範例會以氣象資料為例來示範 API for Table 的功能。 代表氣象觀察的物件會使用 API for Table 來儲存和擷取,其中包括儲存具有其他屬性的物件以藉此示範 API for Table 的無架構功能。 下圖顯示在瀏覽器中執行的本機應用程式,其中包含儲存在 Azure Cosmos DB for Table 中的氣象資料。

A screenshot of the finished application, which shows data stored in an Azure Cosmos DB table using the API for Table.

1 - 建立 Azure Cosmos DB 帳戶

您必須先建立 Azure Cosmos DB 資料表 API 帳戶,其中會包含您應用程式中所使用的資料表。 使用 Azure 入口網站、Azure CLI 或 Azure PowerShell 建立帳戶。

登入 Azure 入口網站,並遵循下列步驟來建立 Azure Cosmos DB 帳戶。

指示 Screenshot
在 Azure 入口網站中:
  1. 在 Azure 入口網站頂端的搜尋列中,輸入「cosmos db」。
  2. 在出現在搜尋列下方的功能表上,選取 [服務] 下標示為 [Azure Cosmos DB] 的項目。
A screenshot showing how to use the search box in the top tool bar to find Azure Cosmos DB accounts in Azure.
在 [Azure Cosmos DB] 頁面上,選取 [+ 建立] A screenshot showing the Create button location on the Azure Cosmos DB accounts page in Azure.
在 [選取 API 選項] 頁面上,選擇 [Azure 資料表] 選項。 A screenshot showing the Azure Table option as the correct option to select.
在 [建立 Azure Cosmos DB 帳戶 - Azure 資料表] 頁面上,以如下方式填寫表單。
  1. 選取 [資源群組] 下的 [新建] 連結,以為名為 rg-msdocs-tables-sdk-demo 的儲存體帳戶建立全新資源群組。
  2. 將您的儲存體帳戶命名為 cosmos-msdocs-tables-sdk-demo-XYZ,其中 XYZ 為任意三個隨機字元,藉此建立出唯一的帳戶名稱。 Azure Cosmos DB 帳戶名稱的長度必須介於 3 到 44 個字元之間,且只能包含小寫字母、數字或連字號 (-) 字元。
  3. 選取儲存體帳戶的區域。
  4. 選取 [標準] 效能。
  5. 在 [容量模式] 下,為此範例選取 [已佈建輸送量]
  6. 針對此範例,請選取 [套用免費階層折扣] 下的 [套用]
  7. 選取畫面底部的 [檢閱 + 建立] 按鈕,然後在摘要畫面上選取 [建立] 以建立 Azure Cosmos DB 帳戶。 此程序可能需要幾分鐘的時間。
A screenshot showing how to fill out the fields on the Azure Cosmos DB Account creation page.

2 - 建立資料表

接下來,您必須在 Azure Cosmos DB 帳戶內建立資料表以供應用程式使用。 與傳統資料庫不同的是,您只需要指定資料表的名稱,而無須指定資料表中的屬性 (資料行)。 當資料載入至資料表時,系統會視需要自動建立屬性 (資料行)。

Azure 入口網站中完成下列步驟,以在您的 Azure Cosmos DB 帳戶內建立資料表。

指示 Screenshot
在 Azure 入口網站中,瀏覽至 Azure Cosmos DB 帳戶的概觀頁面。
  1. 您可以在頂端的搜尋列中輸入 Azure Cosmos DB 帳戶的名稱 (cosmos-msdocs-tables-sdk-demo-XYZ),並在資源標題下方查看,以瀏覽至 Azure Cosmos DB 帳戶的概觀頁面。

  2. 選取 Azure Cosmos DB 帳戶的名稱,以移至 [概觀] 頁面。

A screenshot showing how to use the search box in the top tool bar to find your Azure Cosmos DB account.
在 [概觀] 頁面上,選取 [+ 新增資料表]。 [新增資料表] 對話方塊會從頁面右側滑出。 A screenshot showing the location of the Add Table button.
在 [新增資料表] 對話方塊中,以如下方式填寫表單。
  1. 在資料表識別碼中輸入名稱 WeatherData。 此值是資料表的名稱。
  2. 在此範例中,請選取 [資料表輸送量] 底下的 [手動]
  3. 在預估 RU/秒中使用預設值 400。
  4. 選取 [確定] 按鈕以建立資料表。
A screenshot showing how to New Table dialog box for an Azure Cosmos DB table.

3 - 取得 Azure Cosmos DB 連接字串

您的應用程式需要有 CosmosDB 儲存體帳戶的資料表連接字串,才能存取您在 Azure Cosmos DB 中的資料表。 您可以使用 Azure 入口網站、Azure CLI 或 Azure PowerShell 來擷取連接字串。

指示 Screenshot
在 [Azure Cosmos DB 帳戶] 頁面的左側,在 [設定] 標題下找出名為 [連接字串] 的功能表項目,並加以選取。 系統會將您帶往一個頁面,您可以在其中擷取 Azure Cosmos DB 帳戶的連接字串。 A screenshot showing the location of the connection strings link on the Azure Cosmos DB page.
複製要在應用程式中使用的「主要連接字串」值。 A screenshot showing which connection string to select and use in your application.

4 - 安裝適用於 Python 的 Azure 資料表 SDK

在建立 Azure Cosmos DB 帳戶之後,下一個步驟則是安裝 Microsoft 適用於 Python 的 Azure 資料表 SDK。 如需安裝 SDK 的詳細資料,請參閱 GitHub 上適用於 Python 的資料表 SDK 存放庫中的 README.me 檔案。

使用 pip 安裝適用於 Python 的 Azure 資料表用戶端程式庫:

pip install azure-data-tables

別忘了也要在 1-starter-app2-completed-app 資料夾中安裝 requirements.txt


5 - 在 .env 檔案中設定資料表用戶端

從 Azure 入口網站中複製您的 Azure Cosmos DB 帳戶連接字串,並使用複製的連接字串建立 TableServiceClient 物件。 切換至 1-starter-app2-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 資料表作業都會在 webapp 目錄底下位於 helper 檔案的 TableServiceHelper 類別中實作。 您必須在此檔案的頂端匯入 TableServiceClient 類別,才能使用適用於 Python 的 azure.data.tables 用戶端程式庫中的物件。

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 物件。 輸入物件上代表氣象站名稱和觀察日期/時間的屬性會分別對應至 PartitionKeyRowKey 屬性,以形成資料表中該資料列的唯一索引鍵。 然後,輸入模型物件的額外屬性會對應至 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 資料

如果您嘗試使用已經存在於該資料表中的分割區索引鍵/資料列索引鍵組合,來將資料列插入資料表中,您將會收到錯誤訊息。 基於這個理由,一般在將資料列新增至資料表時最好使用 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

使用變數屬性插入或 upsert 資料

使用 Azure Cosmos DB for Table 的其中一項優點,就是如果載入資料表的物件包含任何新屬性,則這些屬性會自動新增至資料表,而值則會儲存在 Azure Cosmos DB 中。 您無須像在傳統資料庫中一樣,執行 ALTER TABLE 之類的 DDL 陳述式來新增資料行。

若之後因資料來源而需要新增或修改所需擷取的資料,或是當不同的輸入端為應用程式提供不同的資料時,這種模型可讓您的應用程式更有彈性。 在範例應用程式中,我們所模擬的氣象站不只能傳送基本的氣象資料,還有一些額外的值。 當具有這些新屬性的物件第一次儲存到資料表中時,對應的屬性 (資料行) 也會自動新增至資料表中。

若要使用資料表 API 插入或 upsert 這類物件,請將可展開物件的屬性對應至 TableEntity 物件,並適當地在 TableClient 物件上使用 create_entityupsert_entity 方法。

在範例應用程式中,upsert_entity 函式也可以使用變數屬性來實作插入或 upsert 資料的函式

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 檔案。

您第一次執行應用程式時不會看到任何資料,因為資料表是空的。 使用應用程式頂端的任意按鈕來將資料新增至資料表。

A screenshot of the application showing the location of the buttons used to insert data into Azure Cosmos DB using the Table API.

選取 [使用資料表實體插入] 按鈕後會開啟一個對話方塊,可讓您使用 TableEntity 物件來插入或 upsert 新的資料列。

A screenshot of the application showing the dialog box used to insert data using a TableEntity object.

選取 [Insert using Expandable] \(使用可展開的資料插入\) 按鈕後會顯示一個對話方塊,讓您使用自訂屬性插入物件,示範 Azure Cosmos DB for Table 如何在需要時自動將屬性 (資料行) 新增至資料表。 使用 [新增自訂欄位] 按鈕來新增一個或多個新的屬性,並示範這項功能。

A screenshot of the application showing the dialog box used to insert data using an object with custom fields.

使用 [插入範例資料] 按鈕,將部分範例資料載入您的 Azure Cosmos DB 資料表中。

  • 對於 1-starter-app 範例資料夾,您至少必須完成 submit_transaction 函式的程式碼,範例資料插入才能運作。

  • 範例資料會從 sample_data.json 檔案載入。 .env 變數 project_root_path 會向應用程式指出可在何處找到此檔案。 例如,如果您是從 1-starter-app2-completed-app 資料夾執行應用程式,請將 project_root_path 設定為 "" (空白)。

A screenshot of the application showing the location of the sample data insert button.

選取頂端功能表中的 [篩選結果] 項目以移至 [篩選結果] 頁面。 在此頁面上,填寫篩選準則以示範如何建立篩選子句並將其傳遞至 Azure Cosmos DB for Table。

A screenshot of the application showing filter results page and highlighting the menu item used to navigate to the page.

清除資源

在您完成應用程式範例後,您應該從 Azure 帳戶中移除與此文章相關的所有 Azure 資源。 您可以藉由刪除資源群組來移除所有資源。

您可以執行下列動作來使用 Azure 入口網站刪除資源群組。

指示 Screenshot
若要移至資源群組,請在搜尋列中輸入該資源群組的名稱。 然後,在 [資源群組] 索引標籤上,選取該資源群組的名稱。 A screenshot showing how to search for a resource group.
從資源群組頁面頂端的工具列中,選取 [刪除資源群組] A screenshot showing the location of the Delete resource group button.
畫面右側會出現一個對話方塊,要求您確認是否要刪除資源群組。
  1. 依指示在文字輸入框中輸入資源群組的完整名稱以確認刪除。
  2. 選取頁面底部的 [刪除] 按鈕。
A screenshot showing the confirmation dialog for deleting a resource group.

下一步

在本快速入門中,您已了解如何建立 Azure Cosmos DB 帳戶、如何使用資料總管來建立資料表,以及如何執行應用程式。 現在,您可以使用資料表 API 來查詢您的資料。