Azure Storage Tables

Azure Storage Tables: CRUD Operations

Azure Table Storage is a NoSQL key-attribute store that allows you to store large amounts of structured, non-relational data. This document covers the fundamental Create, Read, Update, and Delete (CRUD) operations.

Core Concepts


Create (Insert) Operations

To insert a new entity into a table, you need to specify its PartitionKey, RowKey, and any other properties.

Insert Entity

Inserts a single entity. If an entity with the same PartitionKey and RowKey already exists, an error occurs.


// Example using Azure SDK for JavaScript
import { TableClient } from "@azure/data-tables";

async function insertEntity(connectionString, tableName, partitionKey, rowKey, properties) {
    const tableClient = TableClient.fromConnectionString(connectionString, tableName);
    const entity = {
        partitionKey: partitionKey,
        rowKey: rowKey,
        ...properties
    };
    await tableClient.createEntity(entity);
    console.log("Entity created successfully.");
}
            

Insert or Replace Entity

Inserts a new entity or replaces an existing entity with the same PartitionKey and RowKey.


// Example using Azure SDK for JavaScript
async function insertOrReplaceEntity(connectionString, tableName, partitionKey, rowKey, properties) {
    const tableClient = TableClient.fromConnectionString(connectionString, tableName);
    const entity = {
        partitionKey: partitionKey,
        rowKey: rowKey,
        ...properties
    };
    await tableClient.upsertEntity(entity, "Replace");
    console.log("Entity inserted or replaced.");
}
            

Insert or Merge Entity

Inserts a new entity or merges properties into an existing entity with the same PartitionKey and RowKey. Properties that exist in both entities are updated.


// Example using Azure SDK for JavaScript
async function insertOrMergeEntity(connectionString, tableName, partitionKey, rowKey, properties) {
    const tableClient = TableClient.fromConnectionString(connectionString, tableName);
    const entity = {
        partitionKey: partitionKey,
        rowKey: rowKey,
        ...properties
    };
    await tableClient.upsertEntity(entity, "Merge");
    console.log("Entity inserted or merged.");
}
            

Read (Query) Operations

Retrieving data from Azure Table Storage can be done by key, or by querying with filters.

Get Entity by Key

Retrieves a single entity using its PartitionKey and RowKey.


// Example using Azure SDK for JavaScript
async function getEntity(connectionString, tableName, partitionKey, rowKey) {
    const tableClient = TableClient.fromConnectionString(connectionString, tableName);
    const entity = await tableClient.getEntity(partitionKey, rowKey);
    console.log("Retrieved entity:", entity);
    return entity;
}
            

Query Entities

Retrieves a collection of entities that match specified filter criteria. Filters can be applied to properties.


// Example using Azure SDK for JavaScript
async function queryEntities(connectionString, tableName, partitionKeyFilter, otherFilter) {
    const tableClient = TableClient.fromConnectionString(connectionString, tableName);
    const entities = tableClient.listEntities({
        queryOptions: {
            filter: `PartitionKey eq '${partitionKeyFilter}' and ${otherFilter}`
        }
    });
    const results = [];
    for await (const entity of entities) {
        results.push(entity);
    }
    console.log("Query results:", results);
    return results;
}
            

Note: Filtering on PartitionKey and RowKey is highly optimized. Filtering on other properties may result in slower retrieval and higher costs.

Update Operations

Updating entities involves either replacing an entire entity or merging changes.

Update Entity (Replace)

Replaces an existing entity completely. The PartitionKey and RowKey must match an existing entity. All properties of the existing entity are overwritten with the new ones.


// Example using Azure SDK for JavaScript
async function updateEntityReplace(connectionString, tableName, partitionKey, rowKey, newProperties) {
    const tableClient = TableClient.fromConnectionString(connectionString, tableName);
    const updatedEntity = {
        partitionKey: partitionKey,
        rowKey: rowKey,
        ...newProperties
    };
    await tableClient.updateEntity(updatedEntity, "Replace");
    console.log("Entity updated (replaced).");
}
            

Update Entity (Merge)

Merges properties into an existing entity. If a property exists in both the existing and new entity, it is updated. Properties that exist only in the existing entity are retained.


// Example using Azure SDK for JavaScript
async function updateEntityMerge(connectionString, tableName, partitionKey, rowKey, propertiesToMerge) {
    const tableClient = TableClient.fromConnectionString(connectionString, tableName);
    const mergedEntity = {
        partitionKey: partitionKey,
        rowKey: rowKey,
        ...propertiesToMerge
    };
    await tableClient.updateEntity(mergedEntity, "Merge");
    console.log("Entity updated (merged).");
}
            

Delete Operations

Removing data from Azure Table Storage is straightforward.

Delete Entity

Deletes a specific entity identified by its PartitionKey and RowKey.


// Example using Azure SDK for JavaScript
async function deleteEntity(connectionString, tableName, partitionKey, rowKey) {
    const tableClient = TableClient.fromConnectionString(connectionString, tableName);
    await tableClient.deleteEntity(partitionKey, rowKey);
    console.log("Entity deleted.");
}
            

Batch Operations

Azure Table Storage supports batch operations, allowing you to perform multiple CRUD operations (inserts, updates, deletes) in a single request. This can improve performance and reduce network overhead. Note that batch operations within the same partition are transactional.


// Example of a batch operation (simplified)
async function performBatchOperation(connectionString, tableName) {
    const tableClient = TableClient.fromConnectionString(connectionString, tableName);

    const operations = [
        { type: "create", entity: { partitionKey: "P1", rowKey: "R1", value: "A" } },
        { type: "update", entity: { partitionKey: "P1", rowKey: "R1", value: "B" } },
        { type: "delete", partitionKey: "P1", rowKey: "R2" }
    ];

    // Note: Actual batching implementation requires specific SDK methods and considerations
    // for cross-partition vs. same-partition batching.
    // This is a conceptual representation.
    console.log("Performing batch operations (conceptual)...");
    // await tableClient.submitTransaction(operations); // SDK specific method
}