Share via


Uso de Azure SDK para Go con Azure Table

SE APLICA A: Table

Sugerencia

El contenido de este artículo se aplica a Azure Table Storage y Azure Cosmos DB for Table. La API para Table es una oferta prémium que ofrece tablas con rendimiento optimizado, distribución global e índices secundarios automáticos.

En este artículo aprenderá a crear, enumerar y eliminar tablas y entidades de tabla de Azure con Azure SDK para Go.

Azure Table le permite almacenar datos NoSQL estructurados en la nube, lo que proporciona un almacén atributos clave con un diseño sin esquema. Como Azure Table Storage carece de esquema, es fácil adaptar los datos a las necesidades cambiantes de la aplicación. El acceso a los datos y la API de la tabla es una solución rápida y rentable para muchas aplicaciones.

Tanto Table Storage como Azure Cosmos DB se pueden usar para almacenar conjuntos de datos flexibles, como datos de usuarios para aplicaciones web, libretas de direcciones, información de dispositivos u otros tipos de metadatos que el servicio requiera. Una tabla puede almacenar un número cualquiera de entidades y una cuenta de almacenamiento puede incluir un número cualquiera de tablas, hasta alcanzar el límite de capacidad de este tipo de cuenta.

Siga este artículo para aprender a administrar Azure Table Storage mediante Azure SDK para Go.

Prerrequisitos

Configurar el entorno

Para seguir este tutorial, necesitará un grupo de recursos de Azure, una cuenta de almacenamiento y un recurso de tabla. Ejecute los comandos siguientes para configurar el entorno:

  1. Cree un grupo de recursos de Azure.

    az group create --name myResourceGroup --location eastus
    
  2. A continuación, cree una cuenta de almacenamiento de Azure para la nueva tabla de Azure.

    az storage account create --name <storageAccountName> --resource-group myResourceGroup --location eastus --sku Standard_LRS
    
  3. Cree un recurso de tabla.

    az storage table create --account-name <storageAccountName> --account-key 'storageKey' --name mytable
    

Instalar paquetes

Necesitará dos paquetes para administrar Azure Table con Go: azidentity y aztables. El paquete azidentity le ofrece una manera de autenticarse en Azure. Y el paquete aztables le ofrece la posibilidad de administrar el recurso de tablas en Azure. Ejecute los siguientes comandos de Go para instalar estos paquetes:

go get github.com/Azure/azure-sdk-for-go/sdk/data/aztables
go get github.com/Azure/azure-sdk-for-go/sdk/azidentity

Para más información sobre las maneras de autenticarse en Azure, consulte Autenticación de Azure con Azure SDK para Go.

Creación de la aplicación de ejemplo

Una vez instalados los paquetes, cree una aplicación de ejemplo que use Azure SDK para Go para administrar Azure Table. Ejecute el comando go mod para crear un nuevo módulo denominado azTableSample.

go mod init azTableSample

A continuación, cree un archivo denominado main.go y cópielo a continuación:

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    "github.com/Azure/azure-sdk-for-go/sdk/data/aztables"
)

type InventoryEntity struct {
    aztables.Entity
    Price       float32
    Inventory   int32
    ProductName string
    OnSale      bool
}

type PurchasedEntity struct {
    aztables.Entity
    Price float32
    ProductName string
    OnSale bool
}

func getClient() *aztables.Client {
    accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT")
    if !ok {
        panic("AZURE_STORAGE_ACCOUNT environment variable not found")
    }

    tableName, ok := os.LookupEnv("AZURE_TABLE_NAME")
    if !ok {
        panic("AZURE_TABLE_NAME environment variable not found")
    }

    cred, err := azidentity.NewDefaultAzureCredential(nil)
    if err != nil {
        panic(err)
    }
    serviceURL := fmt.Sprintf("https://%s.table.core.windows.net/%s", accountName, tableName)
    client, err := aztables.NewClient(serviceURL, cred, nil)
    if err != nil {
        panic(err)
    }
    return client
}

func createTable(client *aztables.Client) {
    //TODO: Check access policy, Storage Blob Data Contributor role needed
    _, err := client.Create(context.TODO(), nil)
    if err != nil {
        panic(err)
    }
}

func addEntity(client *aztables.Client) {
    myEntity := InventoryEntity{
        Entity: aztables.Entity{
            PartitionKey: "pk001",
            RowKey:       "rk001",
        },
        Price:       3.99,
        Inventory:   20,
        ProductName: "Markers",
        OnSale:      false,
    }

    marshalled, err := json.Marshal(myEntity)
    if err != nil {
        panic(err)
    }

    _, err = client.AddEntity(context.TODO(), marshalled, nil) // TODO: Check access policy, need Storage Table Data Contributor role
    if err != nil {
        panic(err)
    }
}

func listEntities(client *aztables.Client) {
    listPager := client.List(nil)
    pageCount := 0
    for listPager.More() {
        response, err := listPager.NextPage(context.TODO())
        if err != nil {
            panic(err)
        }
        fmt.Printf("There are %d entities in page #%d\n", len(response.Entities), pageCount)
        pageCount += 1
    }
}

func queryEntity(client *aztables.Client) {
    filter := fmt.Sprintf("PartitionKey eq '%v' or RowKey eq '%v'", "pk001", "rk001")
    options := &aztables.ListEntitiesOptions{
        Filter: &filter,
        Select: to.StringPtr("RowKey,Price,Inventory,ProductName,OnSale"),
        Top:    to.Int32Ptr(15),
    }

    pager := client.List(options)
    for pager.More() {
        resp, err := pager.NextPage(context.Background())
        if err != nil {
            panic(err)
        }
        for _, entity := range resp.Entities {
            var myEntity PurchasedEntity 
            err = json.Unmarshal(entity, &myEntity)
            if err != nil {
                panic(err)
            }
            fmt.Println("Return custom type [PurchasedEntity]")
            fmt.Printf("Price: %v; ProductName: %v; OnSale: %v\n", myEntity.Price, myEntity.ProductName, myEntity.OnSale)
        }
    }
}

func deleteEntity(client *aztables.Client) {
    _, err := client.DeleteEntity(context.TODO(), "pk001", "rk001", nil)
    if err != nil {
        panic(err)
    }
}

func deleteTable(client *aztables.Client) {
    _, err := client.Delete(context.TODO(), nil)
    if err != nil {
        panic(err)
    }
}

func main() {

    fmt.Println("Authenticating...")
    client := getClient()

    fmt.Println("Creating a table...")
    createTable(client)

    fmt.Println("Adding an entity to the table...")
    addEntity(client)

    fmt.Println("Calculating all entities in the table...")
    listEntities(client)

    fmt.Println("Querying a specific entity...")
    queryEntity(client) 

    fmt.Println("Deleting an entity...")
    deleteEntity(client) 

    fmt.Println("Deleting a table...")
    deleteTable(client)
}

Importante

Asegúrese de que la cuenta con la que se ha autenticado tiene la directiva de acceso adecuada para administrar la cuenta de almacenamiento de Azure. Para ejecutar el código anterior, debe tener como mínimo el rol Colaborador de datos de Storage Blob y el rol Colaborador de datos de Table Storage.

Ejemplos de código

Autenticar el cliente

// Lookup environment variables
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT")
if !ok {
  panic("AZURE_STORAGE_ACCOUNT environment variable not found")
}

tableName, ok := os.LookupEnv("AZURE_TABLE_NAME")
if !ok {
  panic("AZURE_TABLE_NAME environment variable not found")
}

// Create a credential
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
  panic(err)
}

// Create a table client
serviceURL := fmt.Sprintf("https://%s.table.core.windows.net/%s", accountName, tableName)
client, err := aztables.NewClient(serviceURL, cred, nil)
if err != nil {
  panic(err)
}

Creación de una tabla

// Create a table and discard the response
_, err := client.Create(context.TODO(), nil)
if err != nil {
  panic(err)
}

Crear una entidad

// Define the table entity as a custom type
type InventoryEntity struct {
    aztables.Entity
    Price       float32
    Inventory   int32
    ProductName string
    OnSale      bool
}

// Define the entity values
myEntity := InventoryEntity{
    Entity: aztables.Entity{
        PartitionKey: "pk001",
        RowKey:       "rk001",
    },
    Price:       3.99,
    Inventory:   20,
    ProductName: "Markers",
    OnSale:      false,
}

// Marshal the entity to JSON
marshalled, err := json.Marshal(myEntity)
if err != nil {
    panic(err)
}

// Add the entity to the table
_, err = client.AddEntity(context.TODO(), marshalled, nil) // needs Storage Table Data Contributor role
if err != nil {
    panic(err)
}

Obtención de una entidad

// Define the new custom type
type PurchasedEntity struct {
    aztables.Entity
    Price       float32
    ProductName string
    OnSale      bool
}

// Define the query filter and options
filter := fmt.Sprintf("PartitionKey eq '%v' or RowKey eq '%v'", "pk001", "rk001")
options := &aztables.ListEntitiesOptions{
    Filter: &filter,
    Select: to.StringPtr("RowKey,Price,Inventory,ProductName,OnSale"),
    Top:    to.Int32Ptr(15),
}

// Query the table for the entity
pager := client.List(options)
for pager.More() {
    resp, err := pager.NextPage(context.Background())
    if err != nil {
        panic(err)
    }
    for _, entity := range resp.Entities {
        var myEntity PurchasedEntity
        err = json.Unmarshal(entity, &myEntity)
        if err != nil {
            panic(err)
        }
        fmt.Println("Return custom type [PurchasedEntity]")
        fmt.Printf("Price: %v; ProductName: %v; OnSale: %v\n", myEntity.Price, myEntity.ProductName, myEntity.OnSale)
    }
}

Eliminación de una entidad

_, err := client.DeleteEntity(context.TODO(), "pk001", "rk001", nil)
if err != nil {
  panic(err)
}

Eliminar una tabla

_, err := client.Delete(context.TODO(), nil)
if err != nil {
  panic(err)
}

Ejecución del código

Ahora ya solo tiene que ejecutar la aplicación. Pero antes de hacerlo, debe configurar las variables de entorno. Cree dos variables de entorno y establézcalas en el valor adecuado mediante los siguientes comandos:

export AZURE_STORAGE_ACCOUNT=<YourStorageAccountName> 
export AZURE_TABLE_NAME=<YourAzureTableName>

A continuación, ejecute el siguiente comando go run para ejecutar la aplicación:

go run main.go

Limpieza de recursos

Ejecute el comando siguiente para eliminar el grupo de recursos y todos los recursos que queden:

az group delete --resource-group myResourceGroup

Pasos siguientes

En esta guía de inicio rápido, ha obtenido información sobre cómo crear una cuenta de Azure Cosmos DB, crear una tabla mediante el Explorador de datos y ejecutar una aplicación. Ahora ya puede consultar los datos mediante la API para Table.