分享方式:


Azure Functions 的 Azure 數據表輸出系結

使用 Azure 數據表輸出系結,將實體寫入 Azure Cosmos DB for TableAzure 數據表記憶體中的數據表。

如需安裝和設定詳細數據的詳細資訊,請參閱概

注意

此輸出系結僅支持在數據表中建立新的實體。 如果您需要從函式程式代碼更新現有的實體,請改為直接使用 Azure Tables SDK。

重要

本文使用索引標籤來支援多個版本的 Node.js 程式設計模型。 v4 模型已正式推出,旨在為 JavaScript 和 TypeScript 開發人員提供更靈活且更直覺的體驗。 如需 v4 模型運作方式的更多詳細資料,請參閱 Azure Functions Node.js 開發人員指南。 若要深入了解 v3 與 v4 之間的差異,請參閱移轉指南

範例

您可以使用下列其中一種 C# 模式來建立 C# 函式:

  • 隔離的背景工作模型:在與運行時間隔離的背景工作進程中執行的已編譯 C# 函式。 需要隔離的背景工作進程,才能支援在 LTS 和非 LTS 版本 .NET 和 .NET Framework 上執行的 C# 函式。 隔離背景工作進程函式的延伸模組會使用 Microsoft.Azure.Functions.Worker.Extensions.* 命名空間。
  • 同進程模型:在與 Functions 運行時間相同的進程中執行的已編譯 C# 函式。 在此模型的變化中,函式可以使用 C# 腳本來執行,主要支援 C# 入口網站編輯。 進程內函式的延伸模組會使用 Microsoft.Azure.WebJobs.Extensions.* 命名空間。

下列 MyTableData 類別代表資料表中的數據列:

public class MyTableData : Azure.Data.Tables.ITableEntity
{
    public string Text { get; set; }

    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public DateTimeOffset? Timestamp { get; set; }
    public ETag ETag { get; set; }
}

佇列記憶體觸發程式所啟動的下列函式會將新的 MyDataTable 實體寫入名為 OutputTable 的數據表。

[Function("TableFunction")]
[TableOutput("OutputTable", Connection = "AzureWebJobsStorage")]
public static MyTableData Run(
    [QueueTrigger("table-items")] string input,
    [TableInput("MyTable", "<PartitionKey>", "{queueTrigger}")] MyTableData tableInput,
    FunctionContext context)
{
    var logger = context.GetLogger("TableFunction");

    logger.LogInformation($"PK={tableInput.PartitionKey}, RK={tableInput.RowKey}, Text={tableInput.Text}");

    return new MyTableData()
    {
        PartitionKey = "queue",
        RowKey = Guid.NewGuid().ToString(),
        Text = $"Output record with rowkey {input} created at {DateTime.Now}"
    };
}

下列範例顯示使用 HTTP 觸發程式寫入單一數據表數據列的 Java 函式。

public class Person {
    private String PartitionKey;
    private String RowKey;
    private String Name;

    public String getPartitionKey() {return this.PartitionKey;}
    public void setPartitionKey(String key) {this.PartitionKey = key; }
    public String getRowKey() {return this.RowKey;}
    public void setRowKey(String key) {this.RowKey = key; }
    public String getName() {return this.Name;}
    public void setName(String name) {this.Name = name; }
}

public class AddPerson {

    @FunctionName("addPerson")
    public HttpResponseMessage get(
            @HttpTrigger(name = "postPerson", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION, route="persons/{partitionKey}/{rowKey}") HttpRequestMessage<Optional<Person>> request,
            @BindingName("partitionKey") String partitionKey,
            @BindingName("rowKey") String rowKey,
            @TableOutput(name="person", partitionKey="{partitionKey}", rowKey = "{rowKey}", tableName="%MyTableName%", connection="MyConnectionString") OutputBinding<Person> person,
            final ExecutionContext context) {

        Person outPerson = new Person();
        outPerson.setPartitionKey(partitionKey);
        outPerson.setRowKey(rowKey);
        outPerson.setName(request.getBody().get().getName());

        person.setValue(outPerson);

        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(outPerson)
                        .build();
    }
}

下列範例顯示使用 HTTP 觸發程式寫入多個數據表數據列的 Java 函式。

public class Person {
    private String PartitionKey;
    private String RowKey;
    private String Name;

    public String getPartitionKey() {return this.PartitionKey;}
    public void setPartitionKey(String key) {this.PartitionKey = key; }
    public String getRowKey() {return this.RowKey;}
    public void setRowKey(String key) {this.RowKey = key; }
    public String getName() {return this.Name;}
    public void setName(String name) {this.Name = name; }
}

public class AddPersons {

    @FunctionName("addPersons")
    public HttpResponseMessage get(
            @HttpTrigger(name = "postPersons", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION, route="persons/") HttpRequestMessage<Optional<Person[]>> request,
            @TableOutput(name="person", tableName="%MyTableName%", connection="MyConnectionString") OutputBinding<Person[]> persons,
            final ExecutionContext context) {

        persons.setValue(request.getBody().get());

        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(request.getBody().get())
                        .build();
    }
}

下列範例顯示寫入多個數據表實體的數據表輸出系結。

import { app, HttpRequest, HttpResponseInit, InvocationContext, output } from '@azure/functions';

const tableOutput = output.table({
    tableName: 'Person',
    connection: 'MyStorageConnectionAppSetting',
});

interface PersonEntity {
    PartitionKey: string;
    RowKey: string;
    Name: string;
}

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    const rows: PersonEntity[] = [];
    for (let i = 1; i < 10; i++) {
        rows.push({
            PartitionKey: 'Test',
            RowKey: i.toString(),
            Name: `Name ${i}`,
        });
    }
    context.extraOutputs.set(tableOutput, rows);
    return { status: 201 };
}

app.http('httpTrigger1', {
    methods: ['POST'],
    authLevel: 'anonymous',
    extraOutputs: [tableOutput],
    handler: httpTrigger1,
});
const { app, output } = require('@azure/functions');

const tableOutput = output.table({
    tableName: 'Person',
    connection: 'MyStorageConnectionAppSetting',
});

app.http('httpTrigger1', {
    methods: ['POST'],
    authLevel: 'anonymous',
    extraOutputs: [tableOutput],
    handler: async (request, context) => {
        const rows = [];
        for (let i = 1; i < 10; i++) {
            rows.push({
                PartitionKey: 'Test',
                RowKey: i.toString(),
                Name: `Name ${i}`,
            });
        }
        context.extraOutputs.set(tableOutput, rows);
        return { status: 201 };
    },
});

下列範例示範如何從函式將多個實體寫入數據表。

function.json中的系結組

{
  "bindings": [
    {
      "name": "InputData",
      "type": "manualTrigger",
      "direction": "in"
    },
    {
      "tableName": "Person",
      "connection": "MyStorageConnectionAppSetting",
      "name": "TableBinding",
      "type": "table",
      "direction": "out"
    }
  ],
  "disabled": false
}

run.ps1 中的 PowerShell 程序代碼:

param($InputData, $TriggerMetadata)

foreach ($i in 1..10) {
    Push-OutputBinding -Name TableBinding -Value @{
        PartitionKey = 'Test'
        RowKey = "$i"
        Name = "Name $i"
    }
}

下列範例示範如何使用數據表記憶體輸出系結。 將值指派給 name、、 tableNamepartitionKeyconnection,以在function.json設定系table結:

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "message",
      "type": "table",
      "tableName": "messages",
      "partitionKey": "message",
      "connection": "AzureWebJobsStorage",
      "direction": "out"
    },
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

下列函式會產生 rowKey 值的唯一 UUI,並將訊息保存至數據表記憶體。

import logging
import uuid
import json

import azure.functions as func

def main(req: func.HttpRequest, message: func.Out[str]) -> func.HttpResponse:

    rowKey = str(uuid.uuid4())

    data = {
        "Name": "Output binding message",
        "PartitionKey": "message",
        "RowKey": rowKey
    }

    message.set(json.dumps(data))

    return func.HttpResponse(f"Message created with the rowKey: {rowKey}")

屬性

進程內隔離的背景工作進程 C# 連結庫都會使用屬性來定義函式。 C# 文稿會改用function.json組態檔,如 C# 腳本指南中所述

C# 類別庫中,支援 TableInputAttribute 下列屬性:

屬性內容 描述
TableName 要寫入之資料表的名稱。
PartitionKey 要寫入之資料表實體的分割區索引鍵。
RowKey 要寫入之資料表實體的資料列索引鍵。
[連接] 指定如何連線到資料表服務的應用程式設定或設定集合名稱。 請參閱連線

註釋

Java 函式運行時間連結庫中,在 參數上使用 TableOutput 註釋,將值寫入數據表中。 屬性支援下列元素:

元素 描述
name 函式程式碼中所使用的變數名稱,代表資料表或實體。
dataType 定義 Functions 執行時間應該如何處理參數值。 若要深入瞭解,請參閱 dataType
tableName 要寫入之資料表的名稱。
partitionKey 要寫入之資料表實體的分割區索引鍵。
rowKey 要寫入之資料表實體的資料列索引鍵。
connection 指定如何連線到資料表服務的應用程式設定或設定集合名稱。 請參閱連線

組態

下表說明您可以在傳遞至 output.table() 方法的物件options上設定的屬性。

屬性 說明
tableName 要寫入之資料表的名稱。
partitionKey 要寫入之資料表實體的分割區索引鍵。
rowKey 要寫入之資料表實體的資料列索引鍵。
connection 指定如何連線到資料表服務的應用程式設定或設定集合名稱。 請參閱連線

組態

下表說明您在 function.json 檔案中設定的繫結設定屬性。

function.json 屬性 描述
type 必須設定為 table。 當您在 Azure 入口網站中建立繫結時,會自動設定此屬性。
direction 必須設定為 out。 當您在 Azure 入口網站中建立繫結時,會自動設定此屬性。
name 函式程式碼中所使用的變數名稱,代表資料表或實體。 設為 $return 以參考函式傳回值。
tableName 要寫入之資料表的名稱。
partitionKey 要寫入之資料表實體的分割區索引鍵。
rowKey 要寫入之資料表實體的資料列索引鍵。
connection 指定如何連線到資料表服務的應用程式設定或設定集合名稱。 請參閱連線

當您在本機開發時,請在集合中的 local.settings.json 檔案Values中新增應用程式設定。

連線

屬性 connection 是環境組態的參考,指定應用程式應該如何連線到您的數據表服務。 此屬性可以指定:

如果設定的值與單一設定完全相符,又與其他設定的開頭相符,則會使用完全相符項目。

Connection string

若要取得 Azure 資料表記憶體中數據表的 連接字串,請遵循管理記憶體帳戶存取密鑰中所述的步驟。 若要取得 Azure Cosmos DB for Table 中數據表的 連接字串,請遵循 Azure Cosmos DB for Table 常見問題所示的步驟。

此 連接字串 應該儲存在應用程式設定中,其名稱符合系結組態的 屬性所connection指定的值。

如果應用程式設定名稱以 「AzureWebJobs」 開頭,您就只能在這裡指定名稱的其餘部分。 例如,如果您設定 connection 為 「MyStorage」,Functions 運行時間會尋找名為 「AzureWebJobsMyStorage」 的應用程式設定。 如果您保留connection空白,Functions 運行時間會在名為 AzureWebJobsStorage的應用程式設定中使用預設的記憶體 連接字串。

身分識別型連線

如果您使用資料表 API 延伸模組,而不是搭配秘密使用 連接字串,您可以讓應用程式使用 Microsoft Entra 身分識別。 這隻適用於存取 Azure 儲存體 中的數據表時。 若要使用身分識別,您可以在對應至 connection 觸發程式和系結組態中 屬性的通用前置詞下定義設定。

如果您要將 設定 connection 為 「AzureWebJobsStorage」,請參閱 使用身分識別連線到主機記憶體。 針對所有其他連線,擴充功能需要下列屬性:

屬性 環境變數範本 描述 範例值
數據表服務 URI <CONNECTION_NAME_PREFIX>__tableServiceUri1 您使用 HTTPS 配置,連線至 Azure 儲存體 資料表服務的數據平面 URI。 https://<storage_account_name>.table.core.windows.net

1 <CONNECTION_NAME_PREFIX>__serviceUri 可作為別名。 如果提供這兩個窗體,則會 tableServiceUri 使用表單。 serviceUri在 Blob、佇列和/或數據表之間使用整體聯機組態時,無法使用表單。

其他屬性可以設定為自定義連線。 請參閱身分識別型連線的通用屬性

serviceUri當整體聯機組態要跨 Azure 儲存體 中的 Blob、佇列和/或數據表使用時,就無法使用表單。 URI 只能指定資料表服務。 或者,您可以針對相同前置詞下的每個服務提供 URI,以允許使用單一連線。

主控於 Azure Functions 服務時,以身分識別為基礎的連接會使用受控識別。 雖然可以使用 credentialclientID 屬性指定使用者指派的身分識別,但預設會使用系統指派的身分識別。 請注意,支援以資源識別碼來設定使用者指派的身分識別。 在本機開發等其他內容中執行時,雖然這可以自訂,但仍會改用您的開發人員身分識別。 請參閱使用身分識別型連線進行本機開發

授與權限給身分識別

正在使用的任何身分識別,都必須具有執行預期動作的權限。 有關大多數 Azure 服務,意即您需要指派 Azure RBAC 的角色,利用提供這些權限的內建或自訂角色。

重要

部分權限可能會由所有內容都不需要的目標服務公開。 可以的話,請遵循最低權限原則,只授與身分識別所需的權限。 例如,如果應用程式只需要能夠讀取資料來源,請使用只有讀取權限的角色。 不宜指派也允許寫入該服務的角色,因為讀取作業不需要這麼多權限。 同樣地,最好確保角色指派的範圍僅限於需要讀取的資源。

您必須建立角色指派,以在執行階段提供您 Azure 儲存體資料表服務的存取權。 擁有者之類的管理角色不足夠。 下表顯示在正常作業情況下對 Azure 儲存體使用 Azure 資料表延伸模組時建議的內建角色。 您的應用程式可能會根據您寫入的程式碼要求額外的權限。

繫結類型 範例內建角色 (Azure 儲存體1)
輸入繫結 儲存體資料表資料讀取器
輸出繫結 儲存體資料表資料參與者

1 反之,如果您的應用程式連線到 Azure Cosmos DB for Table 中的資料表,則不支援使用身分識別,而連線必須使用連接字串。

使用方式

系結的使用方式取決於延伸模組套件版本,以及函式應用程式中所使用的 C# 形式,這可以是下列其中一項:

隔離式背景工作處理序類別庫編譯的 C# 函式會在與執行階段隔離的處理序中執行。

選擇版本以查看模式和版本的使用量詳細數據。

當您想要讓函式寫入單一實體時,Azure Tables 輸出系結可以系結至下列類型:

類型 描述
實作 [ITableEntity] 的 JSON 可串行化類型 函式會嘗試將一般舊的CLR物件 (POCO) 類型串行化為實體。 此類型必須實作 [ITableEntity] 或具有字串 RowKey 屬性和字串 PartitionKey 屬性。

當您想要函式寫入多個實體時,Azure Tables 輸出系結可以繫結至下列類型:

類型 描述
T[] 其中 T 是其中一個單一實體類型 包含多個實體的陣列。 每個專案都代表一個實體。

針對其他輸出案例,請直接從 Azure.Data.Tables 建立和使用類型。

使用 TableStorageOutput 註釋,從函式輸出資料表記憶體數據列有兩個選項:

選項。 描述
傳回值 藉由將批注套用至函式本身,函式的傳回值會保存為數據表儲存數據列。
命令式 若要明確設定數據表數據列,請將批注套用至類型的 OutputBinding<T>特定參數,其中 T 包含 PartitionKeyRowKey 屬性。 您可以藉由實作 ITableEntity 或繼承 TableEntity來伴隨這些屬性。

傳回 值或使用 context.extraOutputs.set()來設定輸出數據列數據。

若要寫入數據表數據,請使用 Push-OutputBinding Cmdlet,將 參數和-Value參數設定-Name TableBinding為等於數據列數據。 如需詳細資訊, 請參閱 PowerShell 範例

有兩個選項可從函式輸出資料表記憶體資料列訊息:

選項。 描述
傳回值 name function.json 屬性設定為 $return。 使用此設定時,函式的傳回值會保存為數據表記憶體數據列。
命令式 將值傳遞至宣告為 Out 類型的參數的 set 方法。 傳遞至 set 的值會保存為數據表數據列。

如需特定使用量詳細數據,請參閱 範例

例外狀況和傳回碼

繫結 參考
Table 數據表錯誤碼
Blob、數據表、佇列 記憶體錯誤碼
Blob、數據表、佇列 疑難排解

下一步