Azure Functions における Azure Functions の入力バインド

Azure テーブルの入力バインドを使用して、Azure Cosmos DB for Table または Azure Table Storage のテーブルを読み取ります。

セットアップと構成の詳細については、概要に関するページをご覧ください。

重要

この記事では、タブを使用して、Node.js プログラミング モデルの複数のバージョンに対応しています。 v4 モデルは一般提供されており、JavaScript と TypeScript の開発者にとって、より柔軟で直感的なエクスペリエンスが得られるように設計されています。 v4 モデルの動作の詳細については、Azure Functions Node.js 開発者ガイドを参照してください。 v3 と v4 の違いの詳細については、移行ガイドを参照してください。

このバインドに関しては現在、Goのサポートは利用できません。

バインドの使用方法は、拡張機能パッケージのバージョンと、関数アプリで使用される C# のモダリティによって異なり、次のいずれかになります。

分離ワーカー プロセス クラス ライブラリでコンパイルされた C# 関数は、ランタイムから分離されたプロセスで実行されます。

バージョンを選択すると、モードとバージョンの例が表示されます。

次の 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; }
}

Queue Storage トリガーによって開始される次の関数は、入力テーブルから行を取得するために使用されるキューから、行キーを読み取ります。 式 {queueTrigger} は、メッセージのメタデータ (メッセージ文字列) に行キーをバインドします。

[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}"
    };
}

次のキューによってトリガーされる関数は、IEnumerable<T> として最初の5つのエンティティを返します。パーティションキーの値はキュー メッセージとして設定されます。

[Function("TestFunction")]
public static void Run([QueueTrigger("myqueue", Connection = "AzureWebJobsStorage")] string partition,
    [TableInput("inTable", "{queueTrigger}", Take = 5, Filter = "Text eq 'test'", 
    Connection = "AzureWebJobsStorage")] IEnumerable<MyTableData> tableInputs,
    FunctionContext context)
{
    var logger = context.GetLogger("TestFunction");
    logger.LogInformation(partition);
    foreach (MyTableData tableInput in tableInputs)
    {
        logger.LogInformation($"PK={tableInput.PartitionKey}, RK={tableInput.RowKey}, Text={tableInput.Text}");
    }
}

Filter のプロパティと Take のプロパティは、返されるエンティティの数を制限するために使用されます。

次の例では、テーブル ストレージ内の指定したパーティション内にある person オブジェクトの一覧を返す、HTTP によってトリガーされる関数を示します。 この例では、パーティション キーは http ルートから抽出され、tableName と connection は関数の設定からのものです。

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; }
}

@FunctionName("getPersonsByPartitionKey")
public Person[] get(
        @HttpTrigger(name = "getPersons", methods = {HttpMethod.GET}, authLevel = AuthorizationLevel.FUNCTION, route="persons/{partitionKey}") HttpRequestMessage<Optional<String>> request,
        @BindingName("partitionKey") String partitionKey,
        @TableInput(name="persons", partitionKey="{partitionKey}", tableName="%MyTableName%", connection="MyConnectionString") Person[] persons,
        final ExecutionContext context) {

    context.getLogger().info("Got query for person related to persons with partition key: " + partitionKey);

    return persons;
}

TableInput 注釈では、次の例のように、要求の JSON 本文からバインドを抽出することもできます。

@FunctionName("GetPersonsByKeysFromRequest")
public HttpResponseMessage get(
        @HttpTrigger(name = "getPerson", methods = {HttpMethod.GET}, authLevel = AuthorizationLevel.FUNCTION, route="query") HttpRequestMessage<Optional<String>> request,
        @TableInput(name="persons", partitionKey="{partitionKey}", rowKey = "{rowKey}", tableName="%MyTableName%", connection="MyConnectionString") Person person,
        final ExecutionContext context) {

    if (person == null) {
        return request.createResponseBuilder(HttpStatus.NOT_FOUND)
                    .body("Person not found.")
                    .build();
    }

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

次の例では、フィルターを使用して、Azure テーブル内の特定の名前を持つ人物についてクエリを実行し、一致候補の数を 10 件の結果に制限しています。

@FunctionName("getPersonsByName")
public Person[] get(
        @HttpTrigger(name = "getPersons", methods = {HttpMethod.GET}, authLevel = AuthorizationLevel.FUNCTION, route="filter/{name}") HttpRequestMessage<Optional<String>> request,
        @BindingName("name") String name,
        @TableInput(name="persons", filter="Name eq '{name}'", take = "10", tableName="%MyTableName%", connection="MyConnectionString") Person[] persons,
        final ExecutionContext context) {

    context.getLogger().info("Got query for person related to persons with name: " + name);

    return persons;
}

次の例は、キュー トリガーを使用して 1 つのテーブル行を読み取るテーブル入力バインドを示しています。 このバインディングでは partitionKeyrowKey が指定されます。 rowKey 値 "{queueTrigger}" は、行キーがキュー メッセージ文字列から取得されることを示します。

import { app, input, InvocationContext } from '@azure/functions';

const tableInput = input.table({
    tableName: 'Person',
    partitionKey: 'Test',
    rowKey: '{queueTrigger}',
    connection: 'MyStorageConnectionAppSetting',
});

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

export async function storageQueueTrigger1(queueItem: unknown, context: InvocationContext): Promise<void> {
    context.log('Node.js queue trigger function processed work item', queueItem);
    const person = <PersonEntity>context.extraInputs.get(tableInput);
    context.log('Person entity name: ' + person.Name);
}

app.storageQueue('storageQueueTrigger1', {
    queueName: 'myqueue-items',
    connection: 'MyStorageConnectionAppSetting',
    extraInputs: [tableInput],
    handler: storageQueueTrigger1,
});
const { app, input } = require('@azure/functions');

const tableInput = input.table({
    tableName: 'Person',
    partitionKey: 'Test',
    rowKey: '{queueTrigger}',
    connection: 'MyStorageConnectionAppSetting',
});

app.storageQueue('storageQueueTrigger1', {
    queueName: 'myqueue-items',
    connection: 'MyStorageConnectionAppSetting',
    extraInputs: [tableInput],
    handler: (queueItem, context) => {
        context.log('Node.js queue trigger function processed work item', queueItem);
        const person = context.extraInputs.get(tableInput);
        context.log('Person entity name: ' + person.Name);
    },
});

次の関数では、キュー トリガーを使用して、関数への入力として 1 つのテーブル行を読み取ります。

この例では、バインド構成によってテーブルの partitionKey に明示的な値が指定され、式を使用して rowKey に渡しています。 rowKey 式の {queueTrigger} は、行キーがキュー メッセージ文字列から取得されることを示します。

function.json のバインド構成:

{
  "bindings": [
    {
      "queueName": "myqueue-items",
      "connection": "MyStorageConnectionAppSetting",
      "name": "MyQueueItem",
      "type": "queueTrigger",
      "direction": "in"
    },
    {
      "name": "PersonEntity",
      "type": "table",
      "tableName": "Person",
      "partitionKey": "Test",
      "rowKey": "{queueTrigger}",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "in"
    }
  ],
  "disabled": false
}

run.ps1 の PowerShell コード:

param($MyQueueItem, $PersonEntity, $TriggerMetadata)
Write-Host "PowerShell queue trigger function processed work item: $MyQueueItem"
Write-Host "Person entity name: $($PersonEntity.Name)"

次の関数では、HTTP トリガーを使用して、関数への入力として 1 つのテーブル行を読み取ります。

この例では、バインド構成によってテーブルの partitionKey に明示的な値が指定され、式を使用して rowKey に渡しています。 rowKey 式である {id} は、行キーが要求のルートの {id} の部分から取得されることを示します。

import json
import azure.functions as func

app = func.FunctionApp()

@app.route(route="messages/{id}")
@app.table_input(arg_name="messageJSON",
                 connection="AzureWebJobsStorage",
                 table_name="messages",
                 row_key='{id}',
                 partition_key="message")
def table_in_binding(req: func.HttpRequest, messageJSON):
    message = json.loads(messageJSON)
    return func.HttpResponse(f"Table row: {messageJSON}")

この単純なバインドでは、行キー ID を持つ行が見つからないケースをプログラムで処理できません。 より詳細なデータ選択を行う場合は、ストレージ SDK を使用します。

属性

インプロセス分離ワーカー プロセスの C# ライブラリの両方で、属性を使って関数を定義します。 C# スクリプトでは、C# スクリプト ガイドで説明されているように、代わりに function.json 構成ファイルを使用します。

C# クラス ライブラリでは、TableInputAttribute は次のプロパティをサポートしています。

属性のプロパティ 説明
テーブル名 テーブルの名前。
PartitionKey 省略可能。 読み取るテーブル エンティティのパーティション キー。
RowKey 省略可能。 読み取るテーブル エンティティの行キー。
取る 省略可能。 IEnumerable<T> で読み取るエンティティの最大数。 RowKey とは使用できません。
Assert 省略可能。 IEnumerable<T> に読み取るエンティティの OData フィルター式。 RowKey とは使用できません。
接続 テーブル サービスへの接続方法を指定するアプリ設定または設定コレクションの名前。 「接続」を参照してください。

注釈

Java 関数ランタイム ライブラリで、その値がテーブル ストレージに由来するパラメーターで @TableInput 注釈を使用します。 この注釈は、Java のネイティブ型、POJO、または Optional<T> を使用した null 許容値で使用できます。 この注釈は、次の要素をサポートします。

要素 説明
名前 関数コード内のテーブルまたはエンティティを表す変数の名前。
tableName テーブルの名前。
partitionKey 省略可能。 読み取るテーブル エンティティのパーティション キー。
rowKey 省略可能。 読み取るテーブル エンティティの行キー。
取る 省略可能。 読み取るエンティティの最大数。
フィルター 省略可能。 テーブル入力の OData フィルター式。
接続 テーブル サービスへの接続方法を指定するアプリ設定または設定コレクションの名前。 「接続」を参照してください。

構成

次の表では、options メソッドに渡される input.table() オブジェクトに対して設定できるプロパティについて説明します。

プロパティ 説明
tableName テーブルの名前。
partitionKey 省略可能。 読み取るテーブル エンティティのパーティション キー。
rowKey 省略可能。 読み取るテーブル エンティティの行キー。 takefilter は同時に使用できません
取る 省略可能。 返すエンティティの最大数。 rowKey とは使用できません。
フィルター 省略可能。 テーブルから返されるエンティティの OData フィルター式。 rowKey とは使用できません。
接続 テーブル サービスへの接続方法を指定するアプリ設定または設定コレクションの名前。 「接続」を参照してください。

構成

次の表は、function.json ファイルで設定したバインド構成のプロパティを説明しています。

function.json のプロパティ 説明
タイプ table に設定する必要があります。 このプロパティは、Azure Portal でバインドを作成するときに自動で設定されます。
方向 in に設定する必要があります。 このプロパティは、Azure Portal でバインドを作成するときに自動で設定されます。
名前 関数コード内のテーブルまたはエンティティを表す変数の名前。
tableName テーブルの名前。
partitionKey 省略可能。 読み取るテーブル エンティティのパーティション キー。
rowKey 省略可能。 読み取るテーブル エンティティの行キー。 takefilter は同時に使用できません
取る 省略可能。 返すエンティティの最大数。 rowKey とは使用できません。
フィルター 省略可能。 テーブルから返されるエンティティの OData フィルター式。 rowKey とは使用できません。
接続 テーブル サービスへの接続方法を指定するアプリ設定または設定コレクションの名前。 「接続」を参照してください。

ローカルで開発する場合は、 コレクション内の Valuesにアプリケーション設定を追加します。

つながり

connectionプロパティはアプリケーション設定でキーに設定されており、Functionsランタイムが拡張で使用しているストレージアカウントに接続するために使われる値を返します。 接続プロパティ設定の値は接続の種類によって異なります:

  • マネージドID接続: connection プロパティは、複数の設定群が共有する <CONNECTION_NAME_PREFIX> であり、これらが共にストレージアカウントへのアイデンティティベースの接続を定義します。 詳細については、「 同一性接続の定義」を参照してください。
  • Key Vault参照:connectionプロパティ設定は、接続文字列が中央管理されている場所への参照Azure Key Vaultを返します。 詳細については、「Key Vault connectionsの定義」をご覧ください。
  • App Configuration reference:connectionプロパティ設定は接続文字列またはKey Vault参照を返すAzure App Configuration参照を返します。 詳細については、接続記事のAzure App Configurationをご覧ください。
  • Connection string:connectionプロパティ設定は実際のストレージアカウント接続文字列を返します。 接続文字列には共有の秘密鍵が含まれているため、可能であれば管理型アイデンティティ接続の使用を検討すべきです。 詳細については、「 接続の定義」を参照してください。

バインディング接続について詳しく知りたい方は、Azure Functionsの「Manage connection in Connection」をご覧ください。 接続文字列を取得するには、Manage ストレージ アカウントアクセス キーに示されている手順に従います。

connectionをキーやAzureWebJobsStorageという名前のキープレフィックスに設定したり、空文字列に設定した場合、バインディング拡張はデフォルトのホストストレージアカウントを使用します。 詳細については 、「ストレージパフォーマンスの最適化」をご覧ください。

使用法

バインディングの使用方法は、拡張機能パッケージのバージョンと、関数アプリで使用される C# のモダリティによって異なり、次のいずれかになります。

分離ワーカー プロセス クラス ライブラリは、ランタイムから分離されたプロセスで実行されるコンパイル済みの C# 関数です。

バージョンを選択すると、モードとバージョンの使用状況の詳細が表示されます。

1 つのテーブル エンティティを操作する場合、Azure テーブルの入力バインドは次の型にバインドできます。

タイプ 説明
ITableEntity を実装する、JSON シリアル化可能な型 Functions は、エンティティを単純な従来の CLR オブジェクト (POCO) 型に逆シリアル化しようとします。 この型は、ITableEntity を実装するものか、RowKey 文字列プロパティと PartitionKey 文字列プロパティを持つものにする必要があります。
TableEntity1 エンティティを表す、ディクショナリに似た型。

クエリで複数のエンティティを操作する場合、Azure テーブルの入力バインドは次の型にバインドできます。

タイプ 説明
IEnumerable<T> (TITableEntity を実装します) クエリによって返されるエンティティの列挙。 各エントリは 1 つのエンティティを表します。 型 T は、ITableEntity を実装するものか、RowKey 文字列プロパティと PartitionKey 文字列プロパティを持つものにする必要があります。
TableClient1 テーブルに接続されているクライアント。 これによってテーブルの処理を最大限に制御でき、接続に十分なアクセス許可がある場合は、これを使ってテーブルに書き込むことができます。

1 これらの型を使用するには、Microsoft.Azure.Functions.Worker.Extensions.Tables 1.2.0 以降SDK 型バインドの一般的な依存関係に関する記事を参照する必要があります。

TableInput 属性を使用すると、関数をトリガーしたテーブル行にアクセスできます。

context.extraInputs.get() を使用して入力行データを取得します。

データは、name ファイルの name キーによって指定された入力パラメーターに渡されます。 partitionKeyrowKey を指定すると、特定のレコードをフィルター処理できます。

テーブル データは、JSON 文字列として関数に渡されます。 入力json.loadsに示されているように json.loads を呼び出してメッセージを逆シリアル化します。

具体的な使用方法の詳細については、「例」を参照してください。

次のステップ