Share via


Como usar o SDK do Azure para Go com a Tabela do Azure

APLICA-SE A: Tabela

Gorjeta

O conteúdo deste artigo aplica-se ao armazenamento de Tabela do Azure e ao Azure Cosmos DB para Tabela. A API for Table é uma oferta premium para armazenamento de tabelas que oferece tabelas otimizadas para taxa de transferência, distribuição global e índices secundários automáticos.

Neste artigo, você aprenderá a criar, listar e excluir Tabelas e entidades de Tabela do Azure com o SDK do Azure para Go.

A Tabela do Azure permite armazenar dados NoSQL estruturados na nuvem, fornecendo um repositório de atributos de chave com um design sem esquema. Como o armazenamento de Tabela do Azure não tem esquema, é fácil adaptar seus dados às necessidades em evolução de seus aplicativos. O acesso aos dados e à API da tabela é uma solução rápida e econômica para muitos aplicativos.

Você pode usar o armazenamento de tabela ou o Azure Cosmos DB para armazenar conjuntos de dados flexíveis, como dados do usuário para aplicativos Web, catálogos de endereços, informações do dispositivo. Ou outros tipos de metadados que o seu serviço exige. Pode armazenar quantas entidades pretender numa tabela e uma conta do Storage pode conter quantas tabelas pretender, até ao limite de capacidade da conta do Storage.

Siga este artigo para saber como gerenciar o armazenamento de tabela do Azure usando o SDK do Azure para Go.

Pré-requisitos

Configurar o ambiente

Para acompanhar este tutorial, você precisará de um grupo de recursos do Azure, uma conta de armazenamento e um recurso de tabela. Execute os seguintes comandos para configurar seu ambiente:

  1. Criar um grupo de recursos do Azure.

    az group create --name myResourceGroup --location eastus
    
  2. Em seguida, crie uma conta de armazenamento do Azure para sua nova Tabela do Azure.

    az storage account create --name <storageAccountName> --resource-group myResourceGroup --location eastus --sku Standard_LRS
    
  3. Crie um recurso de tabela.

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

Instalar pacotes

Você precisará de dois pacotes para gerenciar a Tabela do Azure com Go; azidentity, e aztables. O azidentity pacote fornece uma maneira de autenticar no Azure. E os aztables pacotes oferecem a capacidade de gerenciar o recurso de tabelas no Azure. Execute os seguintes comandos Go para instalar estes pacotes:

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

Para saber mais sobre as maneiras de autenticar no Azure, confira Autenticação do Azure com o SDK do Azure para Go.

Criar o aplicativo de exemplo

Depois de instalar os pacotes, você cria um aplicativo de exemplo que usa o SDK do Azure para Go para gerenciar a Tabela do Azure. Execute o go mod comando para criar um novo módulo chamado azTableSample.

go mod init azTableSample

Em seguida, crie um arquivo chamado main.goe, em seguida, copie abaixo para ele:

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

Certifique-se de que a conta com a qual você se autenticou tenha a política de acesso adequada para gerenciar sua conta de armazenamento do Azure. Para executar o código acima, sua conta precisa ter, no mínimo, a função de Colaborador de Dados de Blob de Armazenamento e a função de Colaborador de Dados da Tabela de Armazenamento.

Exemplos de código

Autenticar o 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)
}

Criar uma tabela

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

Criar uma entidade

// 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)
}

Obter uma entidade

// 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)
    }
}

Eliminar uma entidade

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

Eliminar uma tabela

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

Executar o código

Tudo o que resta é executar o aplicativo. Mas antes de fazer isso, você precisa configurar suas variáveis de ambiente. Crie duas variáveis de ambiente e defina-as com o valor apropriado usando os seguintes comandos:

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

Em seguida, execute o seguinte go run comando para executar o aplicativo:

go run main.go

Clean up resources (Limpar recursos)

Execute o seguinte comando para excluir o grupo de recursos e todos os recursos restantes:

az group delete --resource-group myResourceGroup

Próximos passos

Neste guia de introdução, aprendeu a criar uma conta do Azure Cosmos DB, a criar uma tabela com o Data Explorer e a executar uma aplicação. Agora você pode consultar seus dados usando a API para Tabela.