T.Radius
T.Radius

Reputation: 63

Conflict - Python insert-update into Azure table storage

Working with Python, I have many processes that need to update/insert data into an Azure table storage at the same time using :

table_service.update_entity(table_name, task) <br/>
table_service.insert_entity(table_name, task)

However, the following error occurs:

<br/>AzureConflictHttpError: Conflict
{"odata.error":{"code":"EntityAlreadyExists","message":{"lang":"en-US","value":"The specified entity already exists.\nRequestId:57d9b721-6002-012d-3d0c-b88bef000000\nTime:2019-01-29T19:55:53.5984026Z"}}} 

Maybe I need to use a global Lock to avoid operating the same Table Entity concurrently but I don't know how to use it

Upvotes: 1

Views: 2520

Answers (2)

spkane31
spkane31

Reputation: 395

Azure Tables has a new SDK available for Python that is in a preview release available on pip, here's an update for the newest library.

On a create method you can use a try/except block to catch the expected error:

from azure.data.tables import TableClient
from azure.core.exceptions import ResourceExistsError

table_client = TableClient.from_connection_string(conn_str, table_name="myTableName")

try:
    table_client.create_entity(entity=my_entity)
except ResourceExistsError:
    print("Entity already exists")

You can use ETag to update entities conditionally after creation.

from azure.data.tables import UpdateMode
from azure.core import MatchConditions
received_entity = table_client.get_entity(
    partition_key="my_partition_key",
    row_key="my_row_key",
)

etag = received_entity._metadata["etag"]

resp = table_client.update_entity(
    entity=my_new_entity,
    etag=etag,
    mode=UpdateMode.REPLACE,
    match_condition=MatchConditions.IfNotModified
)

On update, you can elect for replace or merge, more information here.

(FYI, I am a Microsoft employee on the Azure SDK for Python team)

Upvotes: 2

Zhaoxing Lu
Zhaoxing Lu

Reputation: 6467

There isn't a global "Lock" in Azure Table Storage, since it's using optimistic concurrency via ETag (i.e. If-Match header in raw HTTP requests).

  1. If your thread A is performing insert_entity, it should catch the 409 Conflict error.
  2. If your thread B & C are performing update_entity, they should 412 Precondition Failed error, and use a loop to retrieve the latest entity then try to update the entity again.

For more details, please check Managing Concurrency in the Table Service section in https://azure.microsoft.com/en-us/blog/managing-concurrency-in-microsoft-azure-storage-2/

Upvotes: 0

Related Questions