none
Best approach for inserting into a Azure Storage table from an Azure Function where table name is determined at runtime? RRS feed

  • Question

  • I have an Azure function which takes data from an Azure Storage Queue and adds it to an Azure Storage Table. The issue is that the name of the table can only be determined based on the contents of the queue message, not beforehand.   

    After reading the Azure function documentation on Imperative Binding for blobs for runtime processing,  I found that I could successfully insert into a storage table using Imperative Binding with code like this.

        var tableBinding = await binder.BindAsync<ICollector<MyEntity>>(new TableAttribute(tableName));
        tableBinding.Add(entity);

     The tableName value here is of course derived from the queue message.

    But after doing some experimentation I found that the following code, which is much more familiar when working with the Azure Storage client, also works:

        var storageConnectionString = ConfigurationManager.AppSettings["MyStorageConnectionString"];      
        var storageAccount = CloudStorageAccount.Parse(storageConnectionString);
        var tableClient = storageAccount.CreateCloudTableClient();
        CloudTable table = tableClient.GetTableReference(tableName);
        await table.CreateIfNotExistsAsync();
        TableOperation insertOperation = TableOperation.Insert(myEntity);
        await table.ExecuteAsync(insertOperation);
    Is there any reason to prefer the Imperative Binding approach over the second more familiar approach?


    • Edited by billmcknight Sunday, December 4, 2016 12:47 AM badd grammar
    Sunday, December 4, 2016 12:22 AM

Answers

  • The dynamic binding APIs (Binder) are all about making things simple. If you're already familiar with and comfortable with the raw storage SDK APIs feel free to use them directly :)

    Note: The Table binding supports binding directly to CloudTable, so you can save 5 lines of code above. E.g.:

    #r "Microsoft.WindowsAzure.Storage"
    
    using Microsoft.WindowsAzure.Storage.Table;
    
    public static void Run(..., CloudTable table, TraceWriter log)
    {
        ...
    }

    And the corresponding input binding metadata (use advanced editor):

    {
      "type": "table",
      "name": "table",
      "tableName": "Test",
      "connection": "<your-storage>",
      "direction": "in"
    }

    Mathew Charles [MSFT]






    Tuesday, December 6, 2016 4:43 PM

All replies

  • The dynamic binding APIs (Binder) are all about making things simple. If you're already familiar with and comfortable with the raw storage SDK APIs feel free to use them directly :)

    Note: The Table binding supports binding directly to CloudTable, so you can save 5 lines of code above. E.g.:

    #r "Microsoft.WindowsAzure.Storage"
    
    using Microsoft.WindowsAzure.Storage.Table;
    
    public static void Run(..., CloudTable table, TraceWriter log)
    {
        ...
    }

    And the corresponding input binding metadata (use advanced editor):

    {
      "type": "table",
      "name": "table",
      "tableName": "Test",
      "connection": "<your-storage>",
      "direction": "in"
    }

    Mathew Charles [MSFT]






    Tuesday, December 6, 2016 4:43 PM
  • But I take it that the input binding approach (declarative binding)  assumes you know the name of the table you are adding to before runtime, right?
    Wednesday, December 7, 2016 2:46 AM
  • No, if you bind a POCO object to the queue trigger input and that POCO has a property for the table name, e.g. "TableName", then for the Table input binding table name property you can use a binding expression {TableName} which will bind at runtime to the property from your queue message. Give it a try :)

    Note that if the table doesn't exist, the Table binding will create it, so if you do this you should ensure that your function is authenticated.


    Mathew Charles [MSFT]


    Wednesday, December 7, 2016 7:36 AM
  • Hi Mathew,

    Could you please elaborate a bit further on this (i.e. dynamically set the Table name inside the function), perhaps with a function.json and run.csx example?

    Tuesday, July 25, 2017 6:19 AM