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
- Uma assinatura do Azure - crie uma gratuitamente.
- Go instalado: Versão 1.17 ou superior
- CLI do Azure
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:
Criar um grupo de recursos do Azure.
az group create --name myResourceGroup --location eastus
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
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.go
e, 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.