azure-functions-powershell-worker icon indicating copy to clipboard operation
azure-functions-powershell-worker copied to clipboard

Push-OutputBinding for table storage does not overwrite existing entities

Open spaelling opened this issue 5 years ago • 9 comments

If the rowKey already exists in the table the entity is not overwritten, but an error is raised. This makes Push-OutputBinding a one-trick-pony wrt. table storage and any workaround defeats the purpose of making integration with Azure Table Storage easy and straightforward.

$Entity = @{
    partitionKey = "SOME_PARTITION_KEY"
    rowKey = "key_that_already_exists_in_the_table"
}
Push-OutputBinding -Name outputTable -Value $Entity
# results in an error "The specified entity already exists"

I would suggest adding a -Force parameter that means overwrite existing entries. This should be trivial as instead of using the insert operation you could use the upsert operation.

Not sure if this should then be an insert or replace or a insert or merge. Perhaps something that can be defined in the integration itself, but either will do as a temporary measure.

Or am I missing something since I could find no mention of this issue anywhere?

spaelling avatar Aug 02 '19 08:08 spaelling

@spaelling Have you tried the -Clobber switch (see Push-OutputBinding syntax)?

AnatoliB avatar Aug 03 '19 19:08 AnatoliB

@spaelling Have you tried the -Clobber switch (see Push-OutputBinding syntax)?

Still the same error. Also I do not believe that -Clobber works like this. In some cases Push-OutputBinding only accepts a single output, ex. Http (Wouldn't make sense to output an array of html objects/code). In this case you can use -Clobber to overwrite the existing value, whereas if it was a queue it would add another object to the queue, or overwrite if using -Clobber.

spaelling avatar Aug 05 '19 07:08 spaelling

@spaelling Thank you, I see what you mean, -Clobber is not supposed to solve this. We'll need to think how to make this configurable, as the current behavior is also desirable sometimes: either use -Force as you suggested, or come up with another parameter.

AnatoliB avatar Aug 05 '19 17:08 AnatoliB

@spaelling Thank you, I see what you mean, -Clobber is not supposed to solve this. We'll need to think how to make this configurable, as the current behavior is also desirable sometimes: either use -Force as you suggested, or come up with another parameter.

Perhaps make it work like Out-File where -NoClobber:

NoClobber prevents an existing file from being overwritten and displays a message that the file already exists. By default, if a file exists in the specified path, Out-File overwrites the file without warning.

In the case of table storage the default behavior could be to overwrite an existing row, but one could work around this using the -NoClobber switch.

But it would probably be best to adopt the two upsert operations already established in table storage

  • Insert or replace If the Insert Or Replace Entity operation is used to replace an entity, any properties from the previous entity will be removed if the new entity does not define them. Properties with a null value will also be removed.
  • Insert or merge If the Insert Or Merge Entity operation is used to merge an entity, any properties from the previous entity will be retained if the request does not define or include them. Properties with a null value will also be retained.

You could implement this by adding an -Upsert parameter (only works with table storage)

$Entity = @{
    partitionKey = "SOME_PARTITION_KEY"
    rowKey = "key_that_already_exists_in_the_table"
}
# replaces the existing row with data from $Entity
Push-OutputBinding -Name outputTable -Value $Entity -Upsert Replace

# merges the data from existing row with data from $Entity
Push-OutputBinding -Name outputTable -Value $Entity -Upsert Merge

spaelling avatar Aug 06 '19 07:08 spaelling

#284 would be ideal, but updating Push-Output Binding in spaellings way would at least provide a workable method to get around some Table API issues without having to resort to the Table API SDK directly.

JustinGrote avatar Mar 19 '20 15:03 JustinGrote

Is there already an update on this topic?

julian-wendt avatar Jun 14 '23 19:06 julian-wendt