Azure Table storage bindings for Azure Functions

This article explains how to work with Azure Table storage bindings in Azure Functions. Azure Functions supports input and output bindings for Azure Table storage.

This is reference information for Azure Functions developers. If you're new to Azure Functions, start with the following resources:

Packages - Functions 1.x

The Table storage bindings are provided in the Microsoft.Azure.WebJobs NuGet package, version 2.x. Source code for the package is in the azure-webjobs-sdk GitHub repository.

Support for this binding is automatically provided in all development environments. You don't have to manually install the package or register the extension.

Azure Storage SDK version in Functions 1.x

In Functions 1.x, the Storage triggers and bindings use version 7.2.1 of the Azure Storage SDK (WindowsAzure.Storage NuGet package). If you reference a different version of the Storage SDK, and you bind to a Storage SDK type in your function signature, the Functions runtime may report that it can't bind to that type. The solution is to make sure your project references WindowsAzure.Storage 7.2.1.

Packages - Functions 2.x and higher

The Table storage bindings are provided in the Microsoft.Azure.WebJobs.Extensions.Storage NuGet package, version 3.x. Source code for the package is in the azure-webjobs-sdk GitHub repository.

The following table tells how to add support for this binding in each development environment.

Development environment To add support
Local development - C# class library Install the package
Local development - C# script, JavaScript, F#, Java and Python Register the extension
Portal development Install when adding output binding

To learn how to update existing binding extensions in the portal without having to republish your function app project, see Update your extensions.

Input

Use the Azure Table storage input binding to read a table in an Azure Storage account.

One entity

The following example shows a C# function that reads a single table row.

The row key value "{queueTrigger}" indicates that the row key comes from the queue message string.

public class TableStorage
{
    public class MyPoco
    {
        public string PartitionKey { get; set; }
        public string RowKey { get; set; }
        public string Text { get; set; }
    }

    [FunctionName("TableInput")]
    public static void TableInput(
        [QueueTrigger("table-items")] string input, 
        [Table("MyTable", "MyPartition", "{queueTrigger}")] MyPoco poco, 
        ILogger log)
    {
        log.LogInformation($"PK={poco.PartitionKey}, RK={poco.RowKey}, Text={poco.Text}");
    }
}

IQueryable

The following example shows a C# function that reads multiple table rows where the MyPoco class derives from TableEntity.

public class TableStorage
{
    public class MyPoco : TableEntity
    {
        public string Text { get; set; }
    }

    [FunctionName("TableInput")]
    public static void TableInput(
        [QueueTrigger("table-items")] string input, 
        [Table("MyTable", "MyPartition")] IQueryable<MyPoco> pocos, 
        ILogger log)
    {
        foreach (MyPoco poco in pocos)
        {
            log.LogInformation($"PK={poco.PartitionKey}, RK={poco.RowKey}, Text={poco.Text}");
        }
    }
}

CloudTable

IQueryable isn't supported in the Functions v2 runtime. An alternative is to use a CloudTable method parameter to read the table by using the Azure Storage SDK. Here's an example of a function that queries an Azure Functions log table:

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Table;
using System;
using System.Threading.Tasks;

namespace FunctionAppCloudTable2
{
    public class LogEntity : TableEntity
    {
        public string OriginalName { get; set; }
    }
    public static class CloudTableDemo
    {
        [FunctionName("CloudTableDemo")]
        public static async Task Run(
            [TimerTrigger("0 */1 * * * *")] TimerInfo myTimer, 
            [Table("AzureWebJobsHostLogscommon")] CloudTable cloudTable,
            ILogger log)
        {
            log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");

            TableQuery<LogEntity> rangeQuery = new TableQuery<LogEntity>().Where(
                TableQuery.CombineFilters(
                    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, 
                        "FD2"),
                    TableOperators.And,
                    TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThan, 
                        "t")));

            // Execute the query and loop through the results
            foreach (LogEntity entity in 
                await cloudTable.ExecuteQuerySegmentedAsync(rangeQuery, null))
            {
                log.LogInformation(
                    $"{entity.PartitionKey}\t{entity.RowKey}\t{entity.Timestamp}\t{entity.OriginalName}");
            }
        }
    }
}

For more information about how to use CloudTable, see Get started with Azure Table storage.

If you try to bind to CloudTable and get an error message, make sure that you have a reference to the correct Storage SDK version.

Input - attributes and annotations

In C# class libraries, use the following attributes to configure a table input binding:

  • TableAttribute

    The attribute's constructor takes the table name, partition key, and row key. The attribute can be used on an out parameter or on the return value of the function, as shown in the following example:

    [FunctionName("TableInput")]
    public static void Run(
        [QueueTrigger("table-items")] string input, 
        [Table("MyTable", "Http", "{queueTrigger}")] MyPoco poco, 
        ILogger log)
    {
        ...
    }
    

    You can set the Connection property to specify the storage account to use, as shown in the following example:

    [FunctionName("TableInput")]
    public static void Run(
        [QueueTrigger("table-items")] string input, 
        [Table("MyTable", "Http", "{queueTrigger}", Connection = "StorageConnectionAppSetting")] MyPoco poco, 
        ILogger log)
    {
        ...
    }
    

    For a complete example, see Input - C# example.

  • StorageAccountAttribute

    Provides another way to specify the storage account to use. The constructor takes the name of an app setting that contains a storage connection string. The attribute can be applied at the parameter, method, or class level. The following example shows class level and method level:

    [StorageAccount("ClassLevelStorageAppSetting")]
    public static class AzureFunctions
    {
        [FunctionName("TableInput")]
        [StorageAccount("FunctionLevelStorageAppSetting")]
        public static void Run( //...
    {
        ...
    }
    

The storage account to use is determined in the following order:

  • The Table attribute's Connection property.
  • The StorageAccount attribute applied to the same parameter as the Table attribute.
  • The StorageAccount attribute applied to the function.
  • The StorageAccount attribute applied to the class.
  • The default storage account for the function app ("AzureWebJobsStorage" app setting).

Input - configuration

The following table explains the binding configuration properties that you set in the function.json file and the Table attribute.

function.json property Attribute property Description
type n/a Must be set to table. This property is set automatically when you create the binding in the Azure portal.
direction n/a Must be set to in. This property is set automatically when you create the binding in the Azure portal.
name n/a The name of the variable that represents the table or entity in function code.
tableName TableName The name of the table.
partitionKey PartitionKey Optional. The partition key of the table entity to read. See the usage section for guidance on how to use this property.
rowKey RowKey Optional. The row key of the table entity to read. See the usage section for guidance on how to use this property.
take Take Optional. The maximum number of entities to read in JavaScript. See the usage section for guidance on how to use this property.
filter Filter Optional. An OData filter expression for table input in JavaScript. See the usage section for guidance on how to use this property.
connection Connection The name of an app setting that contains the Storage connection string to use for this binding. If the app setting name begins with "AzureWebJobs", you can specify only the remainder of the name here. For example, if you set connection to "MyStorage", the Functions runtime looks for an app setting that is named "MyStorage". If you leave connection empty, the Functions runtime uses the default Storage connection string in the app setting that is named AzureWebJobsStorage.

When you're developing locally, app settings go into the local.settings.json file.

Input - usage

  • Read one row in

    Set partitionKey and rowKey. Access the table data by using a method parameter T <paramName>. In C# script, paramName is the value specified in the name property of function.json. T is typically a type that implements ITableEntity or derives from TableEntity. The filter and take properties are not used in this scenario.

  • Read one or more rows

    Access the table data by using a method parameter IQueryable<T> <paramName>. In C# script, paramName is the value specified in the name property of function.json. T must be a type that implements ITableEntity or derives from TableEntity. You can use IQueryable methods to do any filtering required. The partitionKey, rowKey, filter, and take properties are not used in this scenario.

    Note

    IQueryable isn't supported in the Functions v2 runtime. An alternative is to use a CloudTable paramName method parameter to read the table by using the Azure Storage SDK. If you try to bind to CloudTable and get an error message, make sure that you have a reference to the correct Storage SDK version.

Output

Use an Azure Table storage output binding to write entities to a table in an Azure Storage account.

Note

This output binding does not support updating existing entities. Use the TableOperation.Replace operation from the Azure Storage SDK to update an existing entity.

The following example shows a C# function that uses an HTTP trigger to write a single table row.

public class TableStorage
{
    public class MyPoco
    {
        public string PartitionKey { get; set; }
        public string RowKey { get; set; }
        public string Text { get; set; }
    }

    [FunctionName("TableOutput")]
    [return: Table("MyTable")]
    public static MyPoco TableOutput([HttpTrigger] dynamic input, ILogger log)
    {
        log.LogInformation($"C# http trigger function processed: {input.Text}");
        return new MyPoco { PartitionKey = "Http", RowKey = Guid.NewGuid().ToString(), Text = input.Text };
    }
}

Output - attributes and annotations

In C# class libraries, use the TableAttribute.

The attribute's constructor takes the table name. The attribute can be used on an out parameter or on the return value of the function, as shown in the following example:

[FunctionName("TableOutput")]
[return: Table("MyTable")]
public static MyPoco TableOutput(
    [HttpTrigger] dynamic input, 
    ILogger log)
{
    ...
}

You can set the Connection property to specify the storage account to use, as shown in the following example:

[FunctionName("TableOutput")]
[return: Table("MyTable", Connection = "StorageConnectionAppSetting")]
public static MyPoco TableOutput(
    [HttpTrigger] dynamic input, 
    ILogger log)
{
    ...
}

For a complete example, see Output - C# example.

You can use the StorageAccount attribute to specify the storage account at class, method, or parameter level. For more information, see Input - attributes.

Output - configuration

The following table explains the binding configuration properties that you set in the function.json file and the Table attribute.

function.json property Attribute property Description
type n/a Must be set to table. This property is set automatically when you create the binding in the Azure portal.
direction n/a Must be set to out. This property is set automatically when you create the binding in the Azure portal.
name n/a The variable name used in function code that represents the table or entity. Set to $return to reference the function return value.
tableName TableName The name of the table.
partitionKey PartitionKey The partition key of the table entity to write. See the usage section for guidance on how to use this property.
rowKey RowKey The row key of the table entity to write. See the usage section for guidance on how to use this property.
connection Connection The name of an app setting that contains the Storage connection string to use for this binding. If the app setting name begins with "AzureWebJobs", you can specify only the remainder of the name here. For example, if you set connection to "MyStorage", the Functions runtime looks for an app setting that is named "MyStorage". If you leave connection empty, the Functions runtime uses the default Storage connection string in the app setting that is named AzureWebJobsStorage.

When you're developing locally, app settings go into the local.settings.json file.

Output - usage

Access the output table entity by using a method parameter ICollector<T> paramName or IAsyncCollector<T> paramName where T includes the PartitionKey and RowKey properties. These properties are often accompanied by implementing ITableEntity or inheriting TableEntity.

Alternatively you can use a CloudTable method parameter to write to the table by using the Azure Storage SDK. If you try to bind to CloudTable and get an error message, make sure that you have a reference to the correct Storage SDK version.

Exceptions and return codes

Binding Reference
Table Table Error Codes
Blob, Table, Queue Storage Error Codes
Blob, Table, Queue Troubleshooting

Next steps