Share via


Come usare Azure SDK per Go con Azure Table

SI APPLICA A: Tabella

Suggerimento

Il contenuto di questo articolo è applicabile alla risorsa di archiviazione di Azure Table e ad Azure Cosmos DB for Table. L'API per Table è un'offerta premium per l'archiviazione di tabelle che offre tabelle ottimizzate per la velocità effettiva, distribuzione globale e indici secondari automatici.

Questo articolo illustra come creare, elencare ed eliminare tabelle di Azure ed entità tabelle con Azure SDK per Go.

Azure Table consente di archiviare dati NoSQL strutturati nel cloud fornendo un archivio di attributi chiave con una progettazione senza schema. Poiché la risorsa di archiviazione di Azure Table è senza schema, è facile adattare i dati alle esigenze in continua evoluzione delle applicazioni. L'accesso ai dati e all'API della tabella è una soluzione rapida e conveniente per molte applicazioni.

È possibile usare la risorsa di archiviazione di Table o Azure Cosmos DB per archiviare set di dati flessibili come i dati utente per applicazioni Web, rubriche, informazioni sui dispositivi, nonché altri tipi di metadati richiesti dal servizio. In una tabella possono essere archiviate il numero desiderato di tabelle e un account di archiviazione può contenere un numero qualsiasi di tabelle, fino a che non viene raggiunto il limite di capacità dell'account di archiviazione.

Seguire questo articolo per informazioni su come gestire la risorsa di archiviazione di Azure Table con Azure SDK per Go.

Prerequisiti

Configurazione dell'ambiente

Per seguire questa esercitazione è necessario un gruppo di risorse di Azure, un account di archiviazione e una risorsa di tabella. Eseguire i seguenti comandi per configurare l'ambiente:

  1. Crea gruppo di risorse di Azure.

    az group create --name myResourceGroup --location eastus
    
  2. Creare quindi un account di archiviazione di Azure per il nuovo Azure Table.

    az storage account create --name <storageAccountName> --resource-group myResourceGroup --location eastus --sku Standard_LRS
    
  3. Creare una risorsa tabella.

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

Installare i pacchetti

Saranno necessari due pacchetti per gestire Azure Table con Go; azidentity e aztables. Il pacchetto azidentity consente di eseguire l'autenticazione di Azure e i pacchetti aztables consentono di gestire la risorsa tabelle in Azure. Eseguire i seguenti comandi Go per installare questi pacchetti:

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

Per altre informazioni su come effettuare l'autenticazione di Azure, vedere Autenticazione di Azure con Azure SDK per Go.

Creare l'applicazione di esempio

Dopo aver installato i pacchetti, si crea un'applicazione di esempio che utilizza Azure SDK per Go per gestire Azure Table. Eseguire il comando go mod per creare un nuovo modulo denominato azTableSample.

go mod init azTableSample

Successivamente, creare un file denominato main.go, quindi copiarlo di seguito:

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

Assicurarsi che l'account autenticato disponga dei criteri di accesso corretti per gestire l'account di archiviazione di Azure. Per eseguire il codice di cui sopra è necessario che l'account abbia come minimo il ruolo Storage Blob Data Contributor e il ruolo Storage Table Data Contributor.

Esempi di codice

Autenticare il client

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

Crea una tabella

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

Creare un'entità

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

Ottenere un'entità

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

Eliminazione di un'entità

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

Elimina una tabella

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

Eseguire il codice

Non rimane che eseguire l'applicazione, ma prima di farlo è necessario configurare le variabili di ambiente. Creare due variabili di ambiente e impostarle sul valore appropriato utilizzando i seguenti comandi:

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

Eseguire quindi il seguente comando go run per eseguire l'app:

go run main.go

Pulire le risorse

Eseguire il seguente comando per eliminare il gruppo di risorse e tutte le risorse rimanenti:

az group delete --resource-group myResourceGroup

Passaggi successivi

In questa guida di avvio rapido si è appreso come creare un account Azure Cosmos DB, come creare una tabella con Esplora dati e come eseguire un'app. È ora possibile eseguire query sui dati usando l'API per Table.