Azure Storage Table CRUD Operations

Learn how to perform Create, Read, Update, and Delete operations on Azure Table Storage.

Azure Table Storage is a NoSQL key-attribute store. It's ideal for storing large amounts of structured, non-relational data that requires a fast, scalable key/attribute model. This tutorial will guide you through the fundamental CRUD (Create, Read, Update, Delete) operations using the Azure SDK for Python.

Prerequisites:
  • An Azure subscription.
  • An Azure Storage account.
  • Python 3.6+ installed.
  • The Azure Tables client library for Python installed: pip install azure-data-tables

1. Setting Up Your Environment

First, you need to get your connection string for your Azure Storage account. You can find this in the Azure portal under your storage account's "Access keys" section.


# Replace with your actual connection string
export AZURE_STORAGE_CONNECTION_STRING="YOUR_AZURE_STORAGE_CONNECTION_STRING"
            

2. Connecting to Azure Table Storage

We'll use the TableServiceClient to interact with our storage account.


from azure.data.tables import TableServiceClient
import os

# Retrieve the connection string from an environment variable
connection_string = os.environ.get("AZURE_STORAGE_CONNECTION_STRING")
table_name = "mySampleTable"

try:
    # Create the TableServiceClient
    table_service_client = TableServiceClient.from_connection_string(connection_string)
    print("Successfully created TableServiceClient.")
except Exception as ex:
    print(f"Error creating TableServiceClient: {ex}")
    exit()
            

3. Creating a Table

If the table doesn't exist, you can create it:


try:
    # Create the table if it doesn't exist
    table_client = table_service_client.get_table_client(table_name=table_name)
    table_client.create_table()
    print(f"Table '{table_name}' created successfully (or already exists).")
except Exception as ex:
    # If the table already exists, we can ignore this error for this example
    if "TableAlreadyExists" in str(ex):
        print(f"Table '{table_name}' already exists.")
    else:
        print(f"Error creating table: {ex}")
            

4. Creating Entities (Rows)

Entities in Azure Table Storage have a mandatory PartitionKey and RowKey, which together form a unique identifier for the entity.


from azure.data.tables import EdmType

# Define entity data
entity1 = {
    "PartitionKey": "users",
    "RowKey": "user1",
    "name": "Alice",
    "email": "alice@example.com",
    "age": 30,
    "is_active": True
}

entity2 = {
    "PartitionKey": "users",
    "RowKey": "user2",
    "name": "Bob",
    "email": "bob@example.com",
    "age": 25,
    "is_active": False,
    "last_login": datetime.datetime.utcnow() # Example of datetime type
}

entities_to_insert = [entity1, entity2]

try:
    inserted_entities = table_client.insert_entities(entities=entities_to_insert)
    print(f"Inserted {len(inserted_entities)} entities.")
    for entity in inserted_entities:
        print(f"  - {entity['PartitionKey']}, {entity['RowKey']}")
except Exception as ex:
    if "Conflict" in str(ex):
        print("One or more entities already exist. Skipping insertion for duplicates.")
    else:
        print(f"Error inserting entities: {ex}")
            

5. Reading Entities

a. Retrieving a Single Entity

Use the PartitionKey and RowKey to retrieve a specific entity.


partition_key_to_get = "users"
row_key_to_get = "user1"

try:
    retrieved_entity = table_client.get_entity(partition_key=partition_key_to_get, row_key=row_key_to_get)
    print(f"\nRetrieved Entity: {retrieved_entity}")
    print(f"  Name: {retrieved_entity.get('name')}")
except Exception as ex:
    print(f"Error retrieving entity: {ex}")
            

b. Querying Entities

You can query entities based on PartitionKey, RowKey, or other properties using OData filter syntax.


# Query all entities in a specific partition
query_filter = "PartitionKey eq 'users'"
print("\nQuerying all users:")
for entity in table_client.query_entities(filter=query_filter):
    print(f"  - {entity.get('name')} (Age: {entity.get('age')})")

# Query entities with a specific condition
query_filter_active = "PartitionKey eq 'users' and is_active eq true"
print("\nQuerying active users:")
for entity in table_client.query_entities(filter=query_filter_active):
    print(f"  - {entity.get('name')}")

# Query entities with a property type and value
# Note: For specific data types, you might need to specify the EdmType
query_filter_age = "PartitionKey eq 'users' and age gt 28"
print("\nQuerying users older than 28:")
for entity in table_client.query_entities(filter=query_filter_age):
    print(f"  - {entity.get('name')} (Age: {entity.get('age')})")
            

6. Updating Entities

You can update an existing entity. If the entity doesn't exist, it will be created with the create_or_replace_entity method.


partition_key_to_update = "users"
row_key_to_update = "user1"

# Fetch the entity to update its properties
try:
    entity_to_update = table_client.get_entity(partition_key=partition_key_to_update, row_key=row_key_to_update)

    # Modify properties
    entity_to_update["age"] = 31
    entity_to_update["city"] = "New York"

    # Update the entity
    updated_entity = table_client.update_entity(entity=entity_to_update, mode="Merge") # "Merge" or "Replace"
    print(f"\nEntity '{row_key_to_update}' updated: {updated_entity}")

    # Verify update
    retrieved_updated = table_client.get_entity(partition_key=partition_key_to_update, row_key=row_key_to_update)
    print(f"Verified update: Age={retrieved_updated.get('age')}, City={retrieved_updated.get('city')}")

except Exception as ex:
    print(f"Error updating entity: {ex}")
            
Tip: Use mode="Merge" to update only specified properties, or mode="Replace" to replace the entire entity with the new one.

7. Deleting Entities

You can delete an entity by providing its PartitionKey and RowKey.


partition_key_to_delete = "users"
row_key_to_delete = "user2"

try:
    table_client.delete_entity(partition_key=partition_key_to_delete, row_key=row_key_to_delete)
    print(f"\nEntity '{row_key_to_delete}' deleted successfully.")

    # Verify deletion by trying to get it
    try:
        table_client.get_entity(partition_key=partition_key_to_delete, row_key=row_key_to_delete)
    except Exception as e:
        print(f"Verification: Entity '{row_key_to_delete}' not found (as expected).")

except Exception as ex:
    print(f"Error deleting entity: {ex}")
            

8. Deleting the Table

You can also delete the entire table when it's no longer needed.


try:
    table_client.delete_table()
    print(f"\nTable '{table_name}' deleted successfully.")
except Exception as ex:
    print(f"Error deleting table: {ex}")
            
Caution: Deleting a table is a permanent operation and cannot be undone.

Conclusion

This tutorial covered the essential CRUD operations for Azure Table Storage using Python. You learned how to connect, create tables and entities, query data with various filters, update existing records, and delete both entities and tables.

Next: Azure Queue Storage CRUD