Como usar o SDK do Azure para linguagem Go com a Tabela do Azure
APLICA-SE AO: Table
Dica
O conteúdo deste artigo se aplica ao Armazenamento de Tabelas do Azure e ao Azure Cosmos DB for Table. A API for Table é uma oferta premium para armazenamento de tabelas que oferece tabelas com taxa de transferência otimizada, distribuição global e índices secundários automáticos.
Neste artigo, você aprenderá a criar, listar e excluir entidades da Tabela e das Tabelas do Azure com o SDK do Azure para linguagem Go.
A Tabela do Azure permite armazenar dados NoSQL estruturados na nuvem, fornecendo um repositório de atributo de chave com um design sem esquema. Como o armazenamento da Tabela do Azure não tem esquema, é fácil adaptar seus dados à medida que as necessidades de seu aplicativo evoluem. O acesso aos dados e à API da tabela é uma solução rápida e econômica para muitos aplicativos.
Você pode usar o armazenamento da Tabela ou o Azure Cosmos DB para armazenar conjuntos de dados flexíveis, como dados de usuário para aplicativos Web, catálogos de endereços, informações sobre dispositivos. Ou outros tipos de metadados que seu serviço exige. Você pode armazenar qualquer número de entidades em uma tabela e uma conta de armazenamento pode conter um número ilimitado de tabelas, até o limite de capacidade da conta de armazenamento.
Siga este artigo para saber como gerenciar o armazenamento da Tabela do Azure usando o SDK do Azure para linguagem Go.
Pré-requisitos
- Uma assinatura do Azure – crie uma gratuitamente.
- Go instalado: versão 1.17 ou superior
- CLI do Azure
Configure seu 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:
Crie 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
Criar 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 a linguagem Go: azidentity e aztables. O pacote azidentity
fornece um modo de autenticar no Azure. E os pacotes aztables
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 diferentes métodos de autenticação no Azure, confira Autenticação do Azure com o SDK do Azure para linguagem Go.
Criar o aplicativo de exemplo
Depois de instalar os pacotes, você cria um aplicativo de exemplo que usa o SDK do Azure para linguagem Go para gerenciar a Tabela do Azure. Execute o comando go mod
para criar um módulo chamado azTableSample
.
go mod init azTableSample
Em seguida, crie um arquivo chamado main.go
e copie o que está abaixo nele:
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
Verifique se a conta com a qual você se autenticou tem 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 Colaborador de Dados de Blob de Armazenamento e a função 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)
}
}
Excluir uma entidade
_, err := client.DeleteEntity(context.TODO(), "pk001", "rk001", nil)
if err != nil {
panic(err)
}
Excluir uma tabela
_, err := client.Delete(context.TODO(), nil)
if err != nil {
panic(err)
}
Executar o código
Agora 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 comando go run
para executar o aplicativo:
go run main.go
Limpar os recursos
Execute o seguinte comando para excluir o grupo de recursos e todos os recursos restantes:
az group delete --resource-group myResourceGroup
Próximas etapas
Neste início rápido, você aprendeu como criar uma conta do BD Cosmos do Azure, como criar uma tabela usando o Data Explorer e como executar um aplicativo. Agora você pode consultar os dados usando a API de Tabela.