Liaisons de sortie Tables Azure pour Azure Functions

Utilisez une liaison de sortie de stockage Table Azure pour écrire des entités dans une table dans Azure Cosmos DB for Table ou Stockage Table Azure.

Pour plus d’informations sur les détails d’installation et de configuration, consultez la vue d’ensemble

Notes

Cette liaison de sortie prend uniquement en charge la création de nouvelles entités dans une table. Si vous devez mettre à jour une entité existante à partir de votre code de fonction, utilisez un kit de développement logiciel (SDK) Tables Azure directement.

Important

Cet article utilise des onglets pour prendre en charge plusieurs versions du modèle de programmation Node.js. Le modèle v4 est en disponibilité générale. Il est conçu pour offrir une expérience plus flexible et intuitive aux développeurs JavaScript et TypeScript. Pour plus d’informations sur le fonctionnement du modèle v4, reportez-vous au guide du développeur Azure Functions Node.js. En savoir plus sur les différences entre v3 et v4 dans le guide de migration.

Exemple

Une fonction C# peut être créée à l’aide de l’un des modes C# suivants :

  • Modèle worker isolé : fonction C# compilée exécutée dans un processus worker isolé du runtime. Le processus Worker isolé est requis pour prendre en charge les fonctions C# exécutées sur les versions LTS et non-LTS de .NET et de .NET Framework. Les extensions pour les fonctions de processus de travail isolés utilisent des espaces de noms Microsoft.Azure.Functions.Worker.Extensions.*.
  • Modèle In-process : fonction C# compilée exécutée dans le même processus que le runtime Functions. Dans une variation de ce modèle, Functions peut être exécuté à l’aide de scripts C#, principalement pris en charge pour la modification du portail C#. Les extensions pour les fonctions in-process utilisent des espaces de noms Microsoft.Azure.WebJobs.Extensions.*.

La classe MyTableData suivante représente une ligne de données dans la table :

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

La fonction suivante, qui est démarrée par un déclencheur Stockage File d’attente, écrit une nouvelle entité MyDataTable dans une table nommée 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}"
    };
}

L’exemple suivant illustre une fonction Java utilisant un déclencheur HTTP pour écrire une seule ligne de table.

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

L’exemple suivant illustre une fonction Java utilisant un déclencheur HTTP pour écrire plusieurs lignes de table.

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

L’exemple suivant montre une liaison de données de sortie de table qui écrit plusieurs entités de table.

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

L'exemple suivant montre comment écrire plusieurs entités dans une table à partir d'une fonction.

Configuration de liaison dans function.json :

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

Code PowerShell dans run.ps1 :

param($InputData, $TriggerMetadata)

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

L’exemple suivant montre comment utiliser la liaison de sortie de stockage de table. Configurez la liaison table est configurée dans le fichier function.json en affectant des valeurs à name, tableName, partitionKey et connection :

{
  "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"
    }
  ]
}

La fonction suivante génère un UUI unique pour la valeur rowKey et conserve le message dans le stockage de table.

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}")

Attributs

Les bibliothèques C# in-process et de processus Worker isolé utilisent des attributs pour définir la fonction. Le script C# utilise à la place un fichier de configuration function.json comme décrit dans le guide de script C#.

Dans les bibliothèques de classes C#, TableInputAttribute prend en charge les propriétés suivantes :

Propriété d’attribut Description
TableName Nom de la table dans laquelle écrire.
PartitionKey Clé de partition de l’entité de table à écrire.
RowKey Clé de ligne de l’entité de table à écrire.
Connection Nom d’un paramètre d’application ou d’une collection de paramètres d’application qui spécifie la façon de se connecter au service de table. Consultez Connexions.

Annotations

Dans la bibliothèque runtime de fonctions Java, utilisez l’annotation TableOutput sur les paramètres pour écrire des valeurs dans vos tables. L’attribut prend en charge les éléments suivants :

Élément Description
name Nom de variable utilisé dans le code de la fonction qui représente la table ou l’entité.
dataType Définit comment le runtime Functions doit traiter la valeur de paramètre. Pour plus d’informations, consultez dataType.
tableName Nom de la table dans laquelle écrire.
partitionKey Clé de partition de l’entité de table à écrire.
rowKey Clé de ligne de l’entité de table à écrire.
connection Nom d’un paramètre d’application ou d’une collection de paramètres d’application qui spécifie la façon de se connecter au service de table. Consultez Connexions.

Configuration

Le tableau suivant explique les propriétés que vous pouvez définir pour l’objet options passé à la méthode output.table().

Propriété Description
tableName Nom de la table dans laquelle écrire.
partitionKey Clé de partition de l’entité de table à écrire.
rowKey Clé de ligne de l’entité de table à écrire.
connection Nom d’un paramètre d’application ou d’une collection de paramètres d’application qui spécifie la façon de se connecter au service de table. Consultez Connexions.

Configuration

Le tableau suivant décrit les propriétés de configuration de liaison que vous définissez dans le fichier function.json.

Propriété function.json Description
type Cette propriété doit être définie sur table. Cette propriété est définie automatiquement lorsque vous créez la liaison dans le portail Azure.
direction Cette propriété doit être définie sur out. Cette propriété est définie automatiquement lorsque vous créez la liaison dans le portail Azure.
name Nom de variable utilisé dans le code de la fonction qui représente la table ou l’entité. La valeur doit être $return pour faire référence à la valeur de retour de la fonction.
tableName Nom de la table dans laquelle écrire.
partitionKey Clé de partition de l’entité de table à écrire.
rowKey Clé de ligne de l’entité de table à écrire.
connection Nom d’un paramètre d’application ou d’une collection de paramètres d’application qui spécifie la façon de se connecter au service de table. Consultez Connexions.

Lorsque vous développez en local, ajoutez vos paramètres d’application dans le fichier local.settings.json de la collection Values.

Connexions

La propriété connection est une référence à la configuration de l’environnement qui spécifie la façon dont l’application doit se connecter à votre service de table. Elle peut spécifier :

Si la valeur configurée est à la fois une correspondance exacte pour un paramètre unique et une correspondance de préfixe pour d’autres paramètres, la correspondance exacte est utilisée.

Chaîne de connexion

Pour obtenir une chaîne de connexion pour les tables dans le Stockage Azure Table, suivez les étapes indiquées dans Gérer les clés d’accès au compte de stockage. Pour obtenir une chaîne de connexion pour les tables dans Azure Cosmos DB pour Table, suivez les étapes indiquées dans la FAQ sur Azure Cosmos DB for Table.

Cette chaîne de connexion doit être stockée dans un paramètre d’application dont le nom correspond à la valeur spécifiée par la propriété connection de la configuration de liaison.

Si le nom du paramètre d’application commence par « AzureWebJobs », vous ne pouvez spécifier que le reste du nom ici. Par exemple, si vous définissez connection sur « MyStorage », le runtime Functions recherche un paramètre d’application nommé « AzureWebJobsMyStorage ». Si vous laissez connection vide, le runtime Functions utilise la chaîne de connexion de stockage par défaut dans le paramètre d’application nommé AzureWebJobsStorage.

Connexions basées sur l’identité

Si vous utilisez l’extension de l’API Tables, au lieu d’utiliser une chaîne de connexion avec un secret, vous pouvez définir l’application pour qu’elle utilise une identité Microsoft Entra. Cela s’applique uniquement lors de l’accès aux tables dans le Stockage Azure. Pour utiliser une identité, vous devez définir les paramètres sous un préfixe commun qui correspond à la propriété connection dans le déclencheur et la configuration de liaison.

Si vous définissez connection sur « AzureWebJobsStorage », consultez la section Connexion au stockage hôte avec une identité. Pour toutes les autres connexions, l’extension nécessite les propriétés suivantes :

Propriété Modèle de variable d’environnement Description Valeur d'exemple
URI du service de table <CONNECTION_NAME_PREFIX>__tableServiceUri1 URI du plan de données du service de table Stockage Azure auquel vous vous connectez, à l’aide du schéma HTTPS. https://<storage_account_name>.table.core.windows.net

1<CONNECTION_NAME_PREFIX>__serviceUri peut être utilisé comme alias. Si les deux formes sont fournies, la forme tableServiceUri est utilisée. La forme serviceUri ne peut pas être utilisée lorsque la configuration globale de la connexion doit être utilisée sur des objets blob, des files d’attente et/ou des tables.

D’autres propriétés peuvent être définies pour personnaliser la connexion. Consultez Propriétés communes pour les connexions basées sur l’identité.

La forme serviceUri ne peut pas être utilisée lorsque la configuration globale de la connexion doit être utilisée sur des objets blob, des files d’attente et/ou des tables dans le Stockage Azure. L’URI ne peut désigner que le service de table. Vous pouvez également fournir un URI spécifique pour chaque service, sous le même préfixe en autorisant l’utilisation d’une connexion unique.

Quand elles sont hébergées dans le service Azure Functions, les connexions basées sur une identité utilisent une identité managée. L’identité attribuée par le système est utilisée par défaut, bien qu’une identité attribuée par l’utilisateur puisse être spécifiée avec les propriétés credential et clientID. Notez que la configuration d’une identité affectée par l’utilisateur avec un ID de ressource n’est pas prise en charge. Lors d’une exécution dans d’autres contextes, tels que le développement local, votre identité de développeur est utilisée à la place, même si cela peut être personnalisé. Consultez Développement local avec connexions basées sur une identité.

Accorder l’autorisation à l’identité

Quelle que soit l’identité utilisée, elle doit avoir les autorisations nécessaires pour effectuer les actions prévues. Pour la plupart des services Azure, cela signifie que vous devez attribuer un rôle dans Azure RBAC en utilisant des rôles intégrés ou personnalisés qui fournissent ces autorisations.

Important

Parmi les autorisations exposées par le service cible, certaines ne sont peut-être pas nécessaires pour tous les contextes. Dans la mesure du possible, adhérez au principe du privilège minimum, en accordant à l’identité uniquement les privilèges nécessaires. Par exemple, si l’application a juste besoin de pouvoir lire à partir d’une source de données, utilisez un rôle qui a uniquement l’autorisation de lecture. Il serait inapproprié d’attribuer un rôle qui autorise aussi l’écriture dans ce service, car ce serait une autorisation excessive pour une opération de lecture. De même, vous voudrez vous assurer que l’attribution de rôle est limitée aux seules ressources qui doivent être lues.

Vous devez créer une attribution de rôle qui donne accès à votre service de table Stockage Azure au moment de l’exécution. Les rôles de gestion comme Propriétaire ne sont pas suffisants. Le tableau suivant présente les rôles intégrés qui sont recommandés quand vous utilisez l’extension Tables Azure sur Stockage Azure dans le cadre d’un fonctionnement normal. Votre application peut nécessiter des autorisations supplémentaires en fonction du code que vous écrivez.

Type de liaison Exemples de rôles intégrés (Stockage Azure1)
Liaison d’entrée Lecteur de données de table du stockage
Liaison de sortie Contributeur aux données de table du stockage

1 Si votre application se connecte à des tables dans Azure Cosmos DB for Table, l’utilisation d’une identité n’est pas prise en charge et la connexion doit utiliser une chaîne de connexion.

Usage

L’utilisation de la liaison dépend de la version du package d’extension et de la modalité C# utilisée dans votre application de fonction, qui peut être l’une des suivantes :

Une bibliothèque de classes de processus Worker isolé est une fonction C# compilée exécutée dans un processus Worker isolé du runtime.

Choisissez une version pour afficher les détails d’utilisation du mode et de la version.

Lorsque vous souhaitez que la fonction écrive dans une seule entité, la liaison de sortie de Tables Azure peut se lier aux types suivants :

Type Description
Un type sérialisable JSON qui implémente [ITableEntity] Functions tente de sérialiser un type d’objet CLR traditionnel (POCO) en tant qu’entité. Le type doit implémenter [ITableEntity] ou avoir une propriété de chaîne RowKey et une propriété de chaîne PartitionKey.

Lorsque vous souhaitez que la fonction écrive dans plusieurs entités, la liaison de sortie de Tables Azure peut se lier aux types suivants :

Type Description
T[]T est l’un des types d’entités uniques Un tableau contenant plusieurs entités. Chaque entrée représente une entité.

Pour d'autres scénarios de sortie, créez et utilisez directement des types à partir d’Azure.Data.Tables.

Il existe deux options pour produire en sortie une ligne de stockage de table à partir d’une fonction en utilisant l’annotation TableStorageOutput :

Options Description
Valeur de retour En appliquant l’annotation à la fonction elle-même, la valeur de retour de la fonction est conservée sous la forme d’une ligne de stockage de table.
impératives ; Pour définir explicitement la ligne de la table, appliquez l’annotation à un paramètre spécifique du type OutputBinding<T>, où T inclut les propriétés PartitionKey et RowKey. Vous pouvez accompagner ces propriétés en implémentant ITableEntity ou en héritant TableEntity.

Définissez les données de ligne de sortie en retournant la valeur ou en utilisant context.extraOutputs.set().

Pour écrire dans des données de table, utilisez la cmdlet Push-OutputBinding, et définissez les paramètres -Name TableBinding et -Value à égalité avec les données de ligne. Pour plus d'informations, consultez l'exemple PowerShell.

Il existe deux options pour générer en sortie un message de ligne de stockage de table à partir d’une fonction :

Options Description
Valeur de retour Définissez la propriété name dans function.json sur $return. Avec cette configuration, la valeur de retour de la fonction est conservée en tant que ligne de stockage de table.
impératives ; Passez une valeur à la méthode set du paramètre déclaré en tant que type Out. La valeur transmise à set est conservée en tant que ligne de table.

Pour des informations spécifiques sur l’utilisation, consultez Exemple.

Exceptions et codes de retour

Liaison Informations de référence
Table de charge de travail Codes d’erreur de table
Objet blob, Table, File d’attente Codes d’erreur de stockage
Objet blob, Table, File d’attente Dépannage

Étapes suivantes