Associações de entrada de Tabelas do Azure para o Azure Functions

Use a associação de entrada Tabelas do Azure para ler uma tabela no Azure Cosmos DB para Tabela ou Armazenamento de Tabela do Azure.

Para obter informações sobre detalhes de instalação e configuração, consulte a visão geral.

Importante

Este artigo usa guias para oferecer suporte a várias versões do modelo de programação Node.js. O modelo v4 está geralmente disponível e foi projetado para ter uma experiência mais flexível e intuitiva para desenvolvedores JavaScript e TypeScript. Para obter mais detalhes sobre como o modelo v4 funciona, consulte o Guia do desenvolvedor do Azure Functions Node.js. Para saber mais sobre as diferenças entre v3 e v4, consulte o guia de migração.

Exemplo

O uso da associação depende da versão do pacote de extensão e da modalidade C# usada em seu aplicativo de função, que pode ser uma das seguintes:

Uma biblioteca de classes de processo de trabalho isolada compilada função C# é executada em um processo isolado do tempo de execução.

Escolha uma versão para ver exemplos para o modo e a versão.

A classe a seguir MyTableData representa uma linha de dados na tabela:

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

A função a seguir, que é iniciada por um gatilho de armazenamento de fila, lê uma chave de linha da fila, que é usada para obter a linha da tabela de entrada. A expressão {queueTrigger} vincula a chave de linha aos metadados da mensagem, que é a cadeia de caracteres da mensagem.

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

A seguinte função acionada por fila retorna as primeiras 5 entidades como um IEnumerable<T>, com o valor da chave de partição definido como a mensagem da fila.

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

As Filter propriedades e Take são usadas para limitar o número de entidades retornadas.

O exemplo a seguir mostra uma função acionada HTTP que retorna uma lista de objetos person que estão em uma partição especificada no armazenamento de tabela. No exemplo, a chave de partição é extraída da rota http e o tableName e a conexão são das configurações da função.

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

A anotação TableInput também pode extrair as associações do corpo json da solicitação, como mostra o exemplo a seguir.

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

O exemplo a seguir usa um filtro para consultar pessoas com um nome específico em uma Tabela do Azure e limita o número de correspondências possíveis a 10 resultados.

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

O exemplo a seguir mostra uma associação de entrada de tabela que usa um gatilho de fila para ler uma única linha de tabela. A ligação especifica a partitionKey e a rowKey. O rowKey valor "{queueTrigger}" indica que a chave de linha vem da cadeia de caracteres de mensagem da fila.

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

A função a seguir usa um gatilho de fila para ler uma única linha de tabela como entrada para uma função.

Neste exemplo, a configuração de associação especifica um valor explícito para a tabela partitionKey e usa uma expressão para passar para o rowKey. A rowKey expressão, {queueTrigger}, indica que a chave de linha vem da cadeia de caracteres de mensagem da fila.

Configuração de vinculação em 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
}

Código do PowerShell em run.ps1:

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

A função a seguir usa um gatilho HTTP para ler uma única linha de tabela como entrada para uma função.

Neste exemplo, a configuração de partitionKey vinculação especifica um valor explícito para a tabela e usa uma expressão para passar para o rowKey. A rowKey expressão, {id} indica que a chave de linha vem da {id} parte da rota na solicitação.

Configuração de vinculação no arquivo function.json :

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

Código Python no arquivo __init__.py :

import json

import azure.functions as func

def main(req: func.HttpRequest, messageJSON) -> func.HttpResponse:

    message = json.loads(messageJSON)
    return func.HttpResponse(f"Table row: {messageJSON}")

Com essa ligação simples, você não pode manipular programaticamente um caso em que nenhuma linha que tenha um ID de chave de linha é encontrada. Para uma seleção de dados mais refinada, use o SDK de armazenamento.


Atributos

As bibliotecas C# do processo de trabalho em processo e isoladas usam atributos para definir a função. Em vez disso, o script C# usa um arquivo de configuração function.json, conforme descrito no guia de script C#.

Em bibliotecas de classe C#, o TableInputAttribute suporta as seguintes propriedades:

Propriedade Attribute Description
TableName O nome da tabela.
PartitionKey Opcional. A chave de partição da entidade da tabela a ser lida.
Chave de linha Opcional. A chave de linha da entidade da tabela a ser lida.
Tome Opcional. O número máximo de entidades a serem lidas em um IEnumerable<T>arquivo . Não pode ser usado com RowKey.
Filtro Opcional. Uma expressão de filtro OData para entidades lerem em um IEnumerable<T>arquivo . Não pode ser usado com RowKey.
Ligação O nome de uma configuração de aplicativo ou coleção de configurações que especifica como se conectar ao serviço de tabela. Consulte Conexões.

Anotações

Na biblioteca de tempo de execução de funções Java, use a @TableInput anotação em parâmetros cujo valor viria do armazenamento de tabela. Essa anotação pode ser usada com tipos Java nativos, POJOs ou valores anuláveis usando Optional<T>. Esta anotação suporta os seguintes elementos:

Elemento Description
Designação O nome da variável que representa a tabela ou entidade no código da função.
nome_da_tabela O nome da tabela.
partitionKey Opcional. A chave de partição da entidade da tabela a ser lida.
rowKey [en] Opcional. A chave de linha da entidade da tabela a ser lida.
tomar Opcional. O número máximo de entidades a ler.
filter Opcional. Uma expressão de filtro OData para entrada de tabela.
conexão O nome de uma configuração de aplicativo ou coleção de configurações que especifica como se conectar ao serviço de tabela. Consulte Conexões.

Configuração

A tabela a seguir explica as propriedades que você pode definir no options objeto passado para o input.table() método.

Property Description
nome_da_tabela O nome da tabela.
partitionKey Opcional. A chave de partição da entidade da tabela a ser lida.
rowKey [en] Opcional. A chave de linha da entidade da tabela a ser lida. Não pode ser usado com take ou filter.
tomar Opcional. O número máximo de entidades a devolver. Não pode ser usado com rowKey.
filter Opcional. Uma expressão de filtro OData para as entidades retornarem da tabela. Não pode ser usado com rowKey.
conexão O nome de uma configuração de aplicativo ou coleção de configurações que especifica como se conectar ao serviço de tabela. Consulte Conexões.

Configuração

A tabela a seguir explica as propriedades de configuração de associação definidas no arquivo function.json .

function.json propriedade Description
type Deve ser definido como table. Essa propriedade é definida automaticamente quando você cria a associação no portal do Azure.
direção Deve ser definido como in. Essa propriedade é definida automaticamente quando você cria a associação no portal do Azure.
Designação O nome da variável que representa a tabela ou entidade no código da função.
nome_da_tabela O nome da tabela.
partitionKey Opcional. A chave de partição da entidade da tabela a ser lida.
rowKey [en] Opcional. A chave de linha da entidade da tabela a ser lida. Não pode ser usado com take ou filter.
tomar Opcional. O número máximo de entidades a devolver. Não pode ser usado com rowKey.
filter Opcional. Uma expressão de filtro OData para as entidades retornarem da tabela. Não pode ser usado com rowKey.
conexão O nome de uma configuração de aplicativo ou coleção de configurações que especifica como se conectar ao serviço de tabela. Consulte Conexões.

Quando estiver desenvolvendo localmente, adicione as configurações do aplicativo no arquivo local.settings.json na Values coleção.

Ligações

A connection propriedade é uma referência à configuração do ambiente que especifica como o aplicativo deve se conectar ao seu serviço de tabela. Pode especificar:

Se o valor configurado for uma correspondência exata para uma única configuração e uma correspondência de prefixo para outras configurações, a correspondência exata será usada.

Connection string

Para obter uma cadeia de conexão para tabelas no armazenamento de tabelas do Azure, siga as etapas mostradas em Gerenciar chaves de acesso da conta de armazenamento. Para obter uma cadeia de conexão para tabelas no Azure Cosmos DB for Table, siga as etapas mostradas nas Perguntas frequentes do Azure Cosmos DB for Table.

Essa cadeia de conexão deve ser armazenada em uma configuração de aplicativo com um nome correspondente ao valor especificado pela connection propriedade da configuração de ligação.

Se o nome da configuração do aplicativo começar com "AzureWebJobs", você poderá especificar apenas o restante do nome aqui. Por exemplo, se você definir connection como "MyStorage", o tempo de execução do Functions procurará uma configuração de aplicativo chamada "AzureWebJobsMyStorage". Se você deixar connection vazio, o tempo de execução do Functions usará a cadeia de conexão de armazenamento padrão na configuração do aplicativo chamada AzureWebJobsStorage.

Conexões baseadas em identidade

Se você estiver usando a extensão da API Tables, em vez de usar uma cadeia de conexão com um segredo, poderá fazer com que o aplicativo use uma identidade do Microsoft Entra. Isso só se aplica ao acessar tabelas no Armazenamento do Azure. Para usar uma identidade, defina as configurações sob um prefixo comum que mapeia para a connection propriedade na configuração de gatilho e ligação.

Se você estiver definindo connection como "AzureWebJobsStorage", consulte Conectando-se ao armazenamento de host com uma identidade. Para todas as outras conexões, a extensão requer as seguintes propriedades:

Property Modelo de variável de ambiente Description Valor de exemplo
URI do serviço de tabela <CONNECTION_NAME_PREFIX>__tableServiceUri1 O URI do plano de dados do serviço de tabela de Armazenamento do Azure ao qual você está se conectando, usando o esquema HTTPS. https://< storage_account_name.table.core.windows.net>

<CONNECTION_NAME_PREFIX>__serviceUri 1 pode ser usado como um alias. Se ambos os formulários forem fornecidos, o tableServiceUri formulário é usado. O serviceUri formulário não pode ser usado quando a configuração geral da conexão deve ser usada em blobs, filas e/ou tabelas.

Outras propriedades podem ser definidas para personalizar a conexão. Consulte Propriedades comuns para conexões baseadas em identidade.

O serviceUri formulário não pode ser usado quando a configuração geral de conexão deve ser usada em blobs, filas e/ou tabelas no Armazenamento do Azure. O URI só pode designar o serviço de tabela. Como alternativa, você pode fornecer um URI especificamente para cada serviço sob o mesmo prefixo, permitindo que uma única conexão seja usada.

Quando hospedadas no serviço Azure Functions, as conexões baseadas em identidade usam uma identidade gerenciada. A identidade atribuída ao sistema é usada por padrão, embora uma identidade atribuída ao usuário possa ser especificada com as credential propriedades e clientID . Observe que nãosuporte para a configuração de uma identidade atribuída pelo usuário com uma ID de recurso. Quando executado em outros contextos, como desenvolvimento local, sua identidade de desenvolvedor é usada, embora isso possa ser personalizado. Consulte Desenvolvimento local com conexões baseadas em identidade.

Conceder permissão à identidade

Qualquer identidade que esteja sendo usada deve ter permissões para executar as ações pretendidas. Para a maioria dos serviços do Azure, isso significa que você precisa atribuir uma função no RBAC do Azure, usando funções internas ou personalizadas que fornecem essas permissões.

Importante

Algumas permissões podem ser expostas pelo serviço de destino que não são necessárias para todos os contextos. Sempre que possível, aderir ao princípio do menor privilégio, concedendo à identidade apenas os privilégios necessários. Por exemplo, se o aplicativo só precisa ser capaz de ler de uma fonte de dados, use uma função que só tenha permissão para ler. Seria inadequado atribuir uma função que também permita escrever a esse serviço, pois isso seria uma permissão excessiva para uma operação de leitura. Da mesma forma, convém garantir que a atribuição de função tenha escopo apenas sobre os recursos que precisam ser lidos.

Você precisará criar uma atribuição de função que forneça acesso ao seu serviço de tabela do Armazenamento do Azure em tempo de execução. Funções de gerenciamento como Proprietário não são suficientes. A tabela a seguir mostra as funções internas recomendadas ao usar a extensão Tabelas do Azure no Armazenamento do Azure em operação normal. Seu aplicativo pode exigir permissões adicionais com base no código que você escreve.

Tipo de vinculação Exemplo de funções internas (Armazenamentodo Azure 1)
Vinculação de entrada Leitor de dados da tabela de armazenamento
Vinculação de saída Contribuidor de dados da tabela de armazenamento

1 Se, em vez disso, seu aplicativo estiver se conectando a tabelas no Azure Cosmos DB for Table, o uso de uma identidade não será suportado e a conexão deverá usar uma cadeia de conexão.

Utilização

O uso da associação depende da versão do pacote de extensão e da modalidade C# usada em seu aplicativo de função, que pode ser uma das seguintes:

Uma biblioteca de classes de processo de trabalho isolada compilada função C# é executada em um processo isolado do tempo de execução.

Escolha uma versão para ver os detalhes de uso do modo e da versão.

Ao trabalhar com uma única entidade de tabela, a associação de entrada Tabelas do Azure pode se vincular aos seguintes tipos:

Tipo Description
Um tipo serializável JSON que implementa ITableEntity Funções tenta desserializar a entidade em um tipo de objeto CLR (POCO) simples. O tipo deve implementar ITableEntity ou ter uma propriedade string RowKey e uma propriedade string PartitionKey .
TableEntity1 A entidade como um tipo de dicionário.

Ao trabalhar com várias entidades de uma consulta, a associação de entrada Tabelas do Azure pode se associar aos seguintes tipos:

Tipo Description
IEnumerable<T> onde T implementa ITableEntity Uma enumeração de entidades retornadas pela consulta. Cada entrada representa uma entidade. O tipo T deve implementar ITableEntity ou ter uma propriedade string RowKey e uma propriedade string PartitionKey .
TableClient1 Um cliente conectado à tabela. Isso oferece o maior controle para processar a tabela e pode ser usado para gravar nela se a conexão tiver permissão suficiente.

1 Para usar esses tipos, você precisa fazer referência a Microsoft.Azure.Functions.Worker.Extensions.Tables 1.2.0 ou posterior e às dependências comuns para associações de tipo SDK.

O atributo TableInput dá acesso à linha da tabela que acionou a função.

Obtenha os dados da linha de entrada usando context.extraInputs.get()o .

Os dados são passados para o parâmetro de entrada conforme especificado pela name chave no arquivo function.json . Especificar O partitionKey e rowKey permite filtrar para registros específicos.

Os dados da tabela são passados para a função como uma cadeia de caracteres JSON. Desserialize a mensagem chamando json.loads como mostrado no exemplo de entrada.

Para obter detalhes de uso específicos, consulte Exemplo.

Próximos passos