Condividi tramite


Driver SQL di Databricks per Go

Databricks SQL Driver for Go è una libreria Go che consente di usare il codice Go per eseguire comandi SQL nelle risorse di calcolo di Azure Databricks. Questo articolo integra databricks SQL Driver for Go README, Informazioni di riferimento sulle API ed esempi.

Requisiti

Introduzione al Driver SQL di Databricks per Go

  1. Nel computer di sviluppo con Go 1.20 o versione successiva già installata e un progetto di codice Go esistente già creato, creare un file go.mod per tenere traccia delle dipendenze del codice Go eseguendo il comando go mod init, ad esempio:

    go mod init sample
    
  2. Prendere una dipendenza dal pacchetto di Databricks SQL Driver for Go eseguendo il comando go mod edit -require, sostituendo v1.5.2 con la versione più recente del pacchetto di Databricks SQL Driver for Go, come indicato nelle versioni:

    go mod edit -require github.com/databricks/databricks-sql-go@v1.5.2
    

    Il file go.mod dovrà risultare simile al seguente:

    module sample
    
    go 1.20
    
    require github.com/databricks/databricks-sql-go v1.5.2
    
  3. Nel progetto creare un file di codice Go che importa il driver SQL di Databricks per Go. L'esempio seguente, in un file denominato main.go con il contenuto seguente, elenca tutti i cluster nell'area di lavoro di Azure Databricks:

    package main
    
    import (
      "database/sql"
      "os"
      _ "github.com/databricks/databricks-sql-go"
    )
    
    func main() {
      dsn := os.Getenv("DATABRICKS_DSN")
    
      if dsn == "" {
        panic("No connection string found. " +
         "Set the DATABRICKS_DSN environment variable, and try again.")
      }
    
      db, err := sql.Open("databricks", dsn)
      if err != nil {
        panic(err)
      }
      defer db.Close()
    
      if err := db.Ping(); err != nil {
        panic(err)
      }
    }
    
  4. Aggiungere eventuali dipendenze del modulo mancanti eseguendo il comando go mod tidy:

    go mod tidy
    

    Nota

    Se viene visualizzato l'errore go: warning: "all" matched no packages, si è dimenticato di aggiungere un file di codice Go che importa il driver SQL di Databricks per Go.

  5. Creare copie di tutti i pacchetti necessari per supportare compilazioni e test dei pacchetti nel modulo main eseguendo il comando go mod vendor:

    go mod vendor
    
  6. Modificare il codice in base alle esigenze per impostare la variabile di ambiente DATABRICKS_DSN per l'autenticazione di Azure Databricks. Consultare anche Connettersi a un stringa di connessione DSN.

  7. Eseguire il file di codice Go, presupponendo che un file denominato main.go, eseguendo il comando go run:

    go run main.go
    
  8. Se non vengono restituiti errori, il driver SQL di Databricks per Go è stato autenticato correttamente con l'area di lavoro di Azure Databricks e connesso al cluster Azure Databricks in esecuzione o a SQL Warehouse in tale area di lavoro.

Connettersi con una stringa di connessione DSN

Per accedere ai cluster e ai data warehouse SQL, usare sql.Open() per creare un handle di database tramite un stringa di connessione DSN (Data Source Name). Questo esempio di codice recupera la stringa di connessione DSN da una variabile di ambiente denominata DATABRICKS_DSN:

package main

import (
  "database/sql"
  "os"
  _ "github.com/databricks/databricks-sql-go"
)

func main() {
  dsn := os.Getenv("DATABRICKS_DSN")

  if dsn == "" {
    panic("No connection string found. " +
          "Set the DATABRICKS_DSN environment variable, and try again.")
  }

  db, err := sql.Open("databricks", dsn)
  if err != nil {
    panic(err)
  }
  defer db.Close()

  if err := db.Ping(); err != nil {
    panic(err)
  }
}

Per specificare il stringa di connessione DSN nel formato corretto, consultare gli esempi di stringa di connessione DSN in Autenticazione. Ad esempio, per l'autenticazione del token di accesso personale di Azure Databricks, usare la sintassi seguente, dove:

  • <personal-access-token> è il token di accesso personale di Azure Databricks dai requisiti.
  • <server-hostname> è il valore Server Hostname in base ai requisiti.
  • <port-number> è il valore Porta dei requisiti, che in genere è 443.
  • <http-path> è il valore del percorso HTTP in base ai requisiti.
  • <paramX=valueX> è uno o più parametri facoltativi elencati più avanti in questo articolo.
token:<personal-access-token>@<server-hostname>:<port-number>/<http-path>?<param1=value1>&<param2=value2>

Ad esempio, per un cluster:

token:dapi12345678901234567890123456789012@adb-1234567890123456.7.azuredatabricks.net:443/sql/protocolv1/o/1234567890123456/1234-567890-abcdefgh

Ad esempio, per un SQL Warehouse:

token:dapi12345678901234567890123456789012@adb-1234567890123456.7.azuredatabricks.net:443/sql/1.0/endpoints/a1b234c5678901d2

Nota

Come procedura consigliata per la sicurezza, non è consigliabile impostare come hardcoded questo DSN stringa di connessione nel codice Go. È invece necessario recuperare questo DSN stringa di connessione da una posizione sicura. Ad esempio, l'esempio di codice riportato in precedenza in questo articolo usava una variabile di ambiente.

Parametri facoltativi

  • I parametri di connessione facoltativi supportati possono essere specificati in <param=value>. Alcuni dei più usati di frequente includono:
    • catalog: imposta il nome del catalogo iniziale nella sessione.
    • schema: imposta il nome dello schema iniziale nella sessione.
    • maxRows: imposta il numero massimo di righe recuperate per richiesta. Il valore predefinito è 10000.
    • timeout: aggiunge il timeout, espresso in secondi, per l'esecuzione di query del server. Il valore predefinito non prevede un timeout.
    • userAgentEntry: usato per identificare i partner. Per ulteriori informazioni, consultare la documentazione del partner.
  • I parametri di sessione facoltativi supportati possono essere specificati in param=value. Alcuni dei più usati di frequente includono:
    • ansi_mode: una stringa booleana. true per le istruzioni di sessione per rispettare le regole specificate dalla specifica SQL ANSI. Il valore predefinito del sistema è false.
    • timezone: stringa, ad esempio America/Los_Angeles. Imposta il fuso orario della sessione. Il valore predefinito del sistema è UTC.

Ad esempio, per un SQL Warehouse:

token:dapi12345678901234567890123456789012@adb-1234567890123456.7.azuredatabricks.net:443/sql/1.0/endpoints/a1b234c5678901d2?catalog=hive_metastore&schema=example&maxRows=100&timeout=60&timezone=America/Sao_Paulo&ansi_mode=true

Connettersi con la funzione NewConnector

In alternativa, usare sql.OpenDB() per creare un handle di database tramite un nuovo oggetto connettore creato con dbsql.NewConnector() (la connessione ai cluster di Azure Databricks e ai data warehouse SQL con un nuovo oggetto connettore richiede la versione 1.0.0 o successiva del driver SQL di Databricks per Go). Ad esempio:

package main

import (
  "database/sql"
  "os"
  dbsql "github.com/databricks/databricks-sql-go"
)

func main() {
  connector, err := dbsql.NewConnector(
    dbsql.WithAccessToken(os.Getenv("DATABRICKS_ACCESS_TOKEN")),
    dbsql.WithServerHostname(os.Getenv("DATABRICKS_HOST")),
    dbsql.WithPort(443),
    dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
  )
  if err != nil {
    panic(err)
  }

  db := sql.OpenDB(connector)
  defer db.Close()

  if err := db.Ping(); err != nil {
    panic(err)
  }
}

Per specificare il set corretto di impostazioni NewConnector, consultare gli esempi in Autenticazione.

Nota

Come procedura consigliata per la sicurezza, non è consigliabile impostare come hardcoded le impostazioni NewConnector nel codice Go. È invece consigliabile recuperare questi valori da una posizione sicura. Ad esempio, il codice precedente usa variabili di ambiente.

Alcune delle opzioni funzionali usate più di frequente includono:

  • WithAccessToken(<access-token>): token di accesso personale di Azure Databricks dai requisiti. Obbligatorio string.
  • WithServerHostname(<server-hostname>): il valore Server Hostname in base ai requisiti. Obbligatorio string.
  • WithPort(<port>): numero di porta del server, in genere 443. Obbligatorio int.
  • WithHTTPPath(<http-path>): il valore del percorso HTTP in base ai requisiti. Obbligatorio string.
  • WithInitialNamespace(<catalog>, <schema>):Il catalogo e il nome dello schema nella sessione. Facoltativo string, string.
  • WithMaxRows(<max-rows>): il numero massimo di righe recuperate per richiesta. Il valore predefinito è 10000. Optional int.
  • WithSessionParams(<params-map>): i parametri di sessione inclusi "fuso orario" e "ansi_mode". Facoltativo map[string]string.
  • WithTimeout(<timeout>). Il timeout (in time.Duration) per l’esecuzione delle query del server. Il valore predefinito non prevede un timeout. Facoltativo.
  • WithUserAgentEntry(<isv-name-plus-product-name>). Usato per identificare i partner. Per ulteriori informazioni, consultare la documentazione del partner. Facoltativo string.

Ad esempio:

connector, err := dbsql.NewConnector(
  dbsql.WithAccessToken(os.Getenv("DATABRICKS_ACCESS_TOKEN")),
  dbsql.WithServerHostname(os.Getenv("DATABRICKS_HOST")),
  dbsql.WithPort(443),
  dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
  dbsql.WithInitialNamespace("samples", "nyctaxi"),
  dbsql.WithMaxRows(100),
  dbsql.SessionParams(map[string]string{"timezone": "America/Sao_Paulo", "ansi_mode": "true"}),
  dbsql.WithTimeout(time.Minute),
  dbsql.WithUserAgentEntry("example-user"),
)

Autenticazione

Databricks SQL Driver for Go supporta i tipi di autenticazione di Azure Databricks seguenti:

Il driver SQL di Databricks per Go non supporta ancora i tipi di autenticazione di Azure Databricks seguenti:

Autenticazione con token di accesso personale di Databricks

Per usare il driver SQL di Databricks per Go con l'autenticazione del token di accesso personale di Azure Databricks, è prima necessario creare un token di accesso personale di Azure Databricks. Per informazioni dettagliate su questo passaggio, vedere Token di accesso personale di Azure Databricks per gli utenti dell'area di lavoro.

Per autenticare il driver SQL di Databricks for Go con un stringa di connessione DSN e l'esempio di codice in Connettersi a un stringa di connessione DSN, usare la sintassi DSN stringa di connessione seguente, dove:

  • <personal-access-token> è il token di accesso personale di Azure Databricks dai requisiti.
  • <server-hostname> è il valore Server Hostname in base ai requisiti.
  • <port-number> è il valore Porta dei requisiti, che in genere è 443.
  • <http-path> è il valore del percorso HTTP in base ai requisiti.

È anche possibile aggiungere uno o più parametri facoltativi elencati in precedenza in questo articolo.

token:<personal-access-token>@<server-hostname>:<port-number>/<http-path>

Per autenticare il driver SQL di Databricks per Go con la funzione NewConnector, usare il frammento di codice seguente e l'esempio di codice in Connetti con la funzione NewConnector, che presuppone che siano state impostate le variabili di ambiente seguenti:

  • DATABRICKS_SERVER_HOSTNAMEimpostato sul valore Nome host server per il cluster o SQL Warehouse.
  • DATABRICKS_HTTP_PATH, impostato sul valore percorso HTTP per il cluster o SQL Warehouse.
  • DATABRICKS_TOKEN, impostato sul token di accesso personale di Azure Databricks.

Per impostare le variabili di ambiente, si veda la documentazione relativa al sistema operativo Windows utilizzato.

connector, err := dbsql.NewConnector(
  dbsql.WithServerHostname(os.Getenv("DATABRICKS_SERVER_HOSTNAME")),
  dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
  dbsql.WithPort(443),
  dbsql.WithAccessToken(os.Getenv("DATABRICKS_TOKEN")),
)

Autenticazione con token di Microsoft Entra ID

Databricks SQL Driver for Go supporta i token ID Microsoft Entra per un utente di Azure Databricks o un'entità servizio Microsoft Entra ID.

Per creare un token di accesso di Microsoft Entra ID, eseguire le operazioni seguenti:

  • Per un utente di Azure Databricks, è possibile usare l'interfaccia della riga di comando di Azure. Consultare Ottenere i token Microsoft Entra ID per gli utenti utilizzando l’interfaccia della riga di comando di Azure.

    I token ID Microsoft Entra hanno una durata predefinita di circa 1 ora. Per creare un nuovo token ID Microsoft Entra, ripetere questo processo.

    Per autenticare il driver SQL di Databricks for Go con un stringa di connessione DSN e l'esempio di codice in Connettersi a un stringa di connessione DSN, usare la sintassi DSN stringa di connessione seguente, dove:

    • <microsoft-entra-id-token> è il token di Microsoft Entra ID.
    • <server-hostname> è il valore Server Hostname in base ai requisiti.
    • <port-number> è il valore Porta dei requisiti, che in genere è 443.
    • <http-path> è il valore del percorso HTTP in base ai requisiti.

    È anche possibile aggiungere uno o più parametri facoltativi elencati in precedenza in questo articolo.

    token:<microsoft-entra-id-token>@<server-hostname>:<port-number>/<http-path>
    

    Per autenticare il driver SQL di Databricks per Go con la funzione NewConnector, usare il frammento di codice seguente e l'esempio di codice in Connetti con la funzione NewConnector, che presuppone che siano state impostate le variabili di ambiente seguenti:

    • DATABRICKS_SERVER_HOSTNAMEimpostato sul valore Nome host server per il cluster o SQL Warehouse.
    • DATABRICKS_HTTP_PATH, impostato sul valore percorso HTTP per il cluster o SQL Warehouse.
    • DATABRICKS_TOKEN, impostato sul token Microsoft Entra ID.

    Per impostare le variabili di ambiente, si veda la documentazione relativa al sistema operativo Windows utilizzato.

    connector, err := dbsql.NewConnector(
      dbsql.WithServerHostname(os.Getenv("DATABRICKS_SERVER_HOSTNAME")),
      dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
      dbsql.WithPort(443),
      dbsql.WithAccessToken(os.Getenv("DATABRICKS_TOKEN")),
    )
    

Autenticazione da utente a computer (U2M) OAuth

Databricks SQL Driver for Go versioni 1.5.0 e successive supportano l'autenticazione da utente a computer (U2M) OAuth.

Per usare il driver SQL di Databricks for Go con un stringa di connessione DSN e l'esempio di codice in Connettersi a un stringa di connessione DSN, usare la sintassi DSN stringa di connessione seguente, dove:

  • <server-hostname> è il valore Server Hostname in base ai requisiti.
  • <port-number> è il valore Porta dei requisiti, che in genere è 443.
  • <http-path> è il valore del percorso HTTP in base ai requisiti.

È anche possibile aggiungere uno o più parametri facoltativi elencati in precedenza in questo articolo.

<server-hostname>:<port-number>/<http-path>?authType=OauthU2M

Per autenticare il driver SQL di Databricks per Go con la funzione NewConnector, è prima necessario aggiungere quanto segue alla dichiarazione import:

"github.com/databricks/databricks-sql-go/auth/oauth/u2m"

Quindi usare il frammento di codice seguente e l'esempio di codice in Connetti con la funzione NewConnector, che presuppone che siano state impostate le variabili di ambiente seguenti:

  • DATABRICKS_SERVER_HOSTNAMEimpostato sul valore Nome host server per il cluster o SQL Warehouse.
  • DATABRICKS_HTTP_PATH, impostato sul valore percorso HTTP per il cluster o SQL Warehouse.

Per impostare le variabili di ambiente, si veda la documentazione relativa al sistema operativo Windows utilizzato.

authenticator, err := u2m.NewAuthenticator(os.Getenv("DATABRICKS_SERVER_HOSTNAME"), 1*time.Minute)
if err != nil {
  panic(err)
}

connector, err := dbsql.NewConnector(
  dbsql.WithServerHostname(os.Getenv("DATABRICKS_SERVER_HOSTNAME")),
  dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
  dbsql.WithPort(443),
  dbsql.WithAuthenticator(authenticator),
)

Autenticazione OAuth da computer a computer (M2M)

Databricks SQL Driver for Go versioni 1.5.2 e successive supportano l'autenticazione da computer a computer (M2M) OAuth.

Per usare il driver SQL di Databricks per Go con l'autenticazione OAuth M2M, è necessario eseguire le operazioni seguenti:

  1. Creare un'entità servizio di Azure Databricks nell'area di lavoro di Azure Databricks e creare un segreto OAuth per tale entità servizio.

    Per creare l'entità servizio e il relativo segreto OAuth, consultare Autenticare l'accesso ad Azure Databricks con un'entità servizio usando OAuth (OAuth M2M). Prendere nota del valore UUID o ID applicazione dell'entità servizio e del valore Secret per il segreto OAuth dell'entità servizio.

  2. Concedere a quell’entità servizio l'accesso al cluster o al warehouse.

    Per concedere all'entità servizio l'accesso al cluster o al warehouse, consultare Autorizzazioni di calcolo o Gestire un data warehouse SQL.

Per autenticare il driver SQL di Databricks for Go con un stringa di connessione DSN e l'esempio di codice in Connettersi a un stringa di connessione DSN, usare la sintassi DSN stringa di connessione seguente, dove:

  • <server-hostname> è il valore Server Hostname in base ai requisiti.
  • <port-number> è il valore Porta dei requisiti, che in genere è 443.
  • <http-path> è il valore del percorso HTTP in base ai requisiti.
  • <client-id> è il valore dell’ID applicazione e UUID dell'entità servizio.
  • <client-secret> è il valore Secret per il segreto OAuth dell'entità servizio.

È anche possibile aggiungere uno o più parametri facoltativi elencati in precedenza in questo articolo.

<server-hostname>:<port-number>/<http-path>?authType=OAuthM2M&clientID=<client-id>&clientSecret=<client-secret>

Per autenticare il driver SQL di Databricks per Go con la funzione NewConnector, è prima necessario aggiungere quanto segue alla dichiarazione import:

"github.com/databricks/databricks-sql-go/auth/oauth/m2m"

Quindi usare il frammento di codice seguente e l'esempio di codice in Connetti con la funzione NewConnector, che presuppone che siano state impostate le variabili di ambiente seguenti:

  • DATABRICKS_SERVER_HOSTNAMEimpostato sul valore Nome host server per il cluster o SQL Warehouse.
  • DATABRICKS_HTTP_PATH, impostato sul valore percorso HTTP per il cluster o SQL Warehouse.
  • DATABRICKS_CLIENT_ID, impostato sul valore dell'ID applicazione e UUID dell'entità servizio.
  • DATABRICKS_CLIENT_SECRET, impostato sul valore del segreto OAuth dell'entità servizio.

Per impostare le variabili di ambiente, si veda la documentazione relativa al sistema operativo Windows utilizzato.

authenticator := m2m.NewAuthenticator(
  os.Getenv("DATABRICKS_CLIENT_ID"),
  os.Getenv("DATABRICKS_CLIENT_SECRET"),
  os.Getenv("DATABRICKS_SERVER_HOSTNAME"),
)

connector, err := dbsql.NewConnector(
  dbsql.WithServerHostname(os.Getenv("DATABRICKS_SERVER_HOSTNAME")),
  dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
  dbsql.WithPort(443),
  dbsql.WithAuthenticator(authenticator),
)

Eseguire query sui dati

L'esempio seguente illustra come richiamare il driver Databricks SQL for Go per eseguire una query base SQL usando una risorsa di calcolo di Azure Databricks. Questo comando restituisce le prime due righe della tabella trips nello schema samples del catalogo nyctaxi.

Questo esempio di codice recupera la stringa di connessione DSN da una variabile di ambiente denominata DATABRICKS_DSN.

package main

import (
  "database/sql"
  "fmt"
  "os"
  "time"

  _ "github.com/databricks/databricks-sql-go"
)

func main() {
  dsn := os.Getenv("DATABRICKS_DSN")

  if dsn == "" {
    panic("No connection string found." +
          "Set the DATABRICKS_DSN environment variable, and try again.")
  }

  db, err := sql.Open("databricks", dsn)
  if err != nil {
    panic(err)
  }

  defer db.Close()

  var (
    tpep_pickup_datetime  time.Time
    tpep_dropoff_datetime time.Time
    trip_distance         float64
    fare_amount           float64
    pickup_zip            int
    dropoff_zip           int
  )

  rows, err := db.Query("SELECT * FROM samples.nyctaxi.trips LIMIT 2")
  if err != nil {
    panic(err)
  }

  defer rows.Close()

  fmt.Print("tpep_pickup_datetime,",
    "tpep_dropoff_datetime,",
    "trip_distance,",
    "fare_amount,",
    "pickup_zip,",
    "dropoff_zip\n")

  for rows.Next() {
    err := rows.Scan(&tpep_pickup_datetime,
      &tpep_dropoff_datetime,
      &trip_distance,
      &fare_amount,
      &pickup_zip,
      &dropoff_zip)
    if err != nil {
      panic(err)
    }

    fmt.Print(tpep_pickup_datetime, ",",
      tpep_dropoff_datetime, ",",
      trip_distance, ",",
      fare_amount, ",",
      pickup_zip, ",",
      dropoff_zip, "\n")
  }

  err = rows.Err()
  if err != nil {
    panic(err)
  }
}

Gestisce i file nei volumi nel catalogo Unity

Il driver SQL di Databricks consente di scrivere file locali in volumi del catalogo Unity, scaricare file dai volumi ed eliminare file dai volumi, come illustrato nell'esempio seguente:

package main

import (
  "context"
  "database/sql"
  "os"

  _ "github.com/databricks/databricks-sql-go"
  "github.com/databricks/databricks-sql-go/driverctx"
)

func main() {
  dsn := os.Getenv("DATABRICKS_DSN")

  if dsn == "" {
    panic("No connection string found." +
      "Set the DATABRICKS_DSN environment variable, and try again.")
  }

  db, err := sql.Open("databricks", dsn)
  if err != nil {
    panic(err)
  }
  defer db.Close()

  // For writing local files to volumes and downloading files from volumes,
  // you must first specify the path to the local folder that contains the
  // files to be written or downloaded.
  // For multiple folders, add their paths to the following string array.
  // For deleting files in volumes, this string array is ignored but must
  // still be provided, so in that case its value can be set for example
  // to an empty string.
  ctx := driverctx.NewContextWithStagingInfo(
    context.Background(),
    []string{"/tmp/"},
  )

  // Write a local file to the path in the specified volume.
  // Specify OVERWRITE to overwrite any existing file in that path.
  db.ExecContext(ctx, "PUT '/tmp/my-data.csv' INTO '/Volumes/main/default/my-volume/my-data.csv' OVERWRITE")

  // Download a file from the path in the specified volume.
  db.ExecContext(ctx, "GET '/Volumes/main/default/my-volume/my-data.csv' TO '/tmp/my-downloaded-data.csv'")

  // Delete a file from the path in the specified volume.
  db.ExecContext(ctx, "REMOVE '/Volumes/main/default/my-volume/my-data.csv'")

  db.Close()
}

Registrazione

Usare github.com/databricks/databricks-sql-go/logger per registrare i messaggi generati dal driver SQL di Databricks per Go. Nell'esempio di codice seguente viene usato sql.Open() per creare un handle di database tramite un stringa di connessione DSN. Questo esempio di codice recupera la stringa di connessione DSN da una variabile di ambiente denominata DATABRICKS_DSN. Tutti i messaggi di log generati al livello debug e sotto vengono scritti nel file results.log.

package main

import (
  "database/sql"
  "io"
  "log"
  "os"

  _ "github.com/databricks/databricks-sql-go"
  dbsqllog "github.com/databricks/databricks-sql-go/logger"
)

func main() {
  dsn := os.Getenv("DATABRICKS_DSN")

  // Use the specified file for logging messages to.
  file, err := os.Create("results.log")
  if err != nil {
    log.Fatal(err)
  }
  defer file.Close()

  writer := io.Writer(file)

  // Log messages at the debug level and below.
  if err := dbsqllog.SetLogLevel("debug"); err != nil {
    log.Fatal(err)
  }

  // Log messages to the file.
  dbsqllog.SetLogOutput(writer)

  if dsn == "" {
    panic("Error: Cannot connect. No connection string found. " +
      "Set the DATABRICKS_DSN environment variable, and try again.")
  }

  db, err := sql.Open("databricks", dsn)
  if err != nil {
    panic(err)
  }
  defer db.Close()

  if err := db.Ping(); err != nil {
    panic(err)
  }
}

Test

Per testare il codice, usare framework di test Go, ad esempio la libreria standard di test. Per testare il codice in condizioni simulate senza chiamare gli endpoint dell'API REST di Azure Databricks o modificare lo stato degli account o delle aree di lavoro di Azure Databricks, usare librerie di simulazione di Go, ad esempio testify.

Ad esempio, dato il file seguente denominato helpers.go contenente una funzione GetDBWithDSNPAT che restituisce una connessione all'area di lavoro di Azure Databricks, una funzione GetNYCTaxiTrips che restituisce dati dalla tabella trips nello schema samples del catalogo nyctaxi e un oggetto PrintNYCTaxiTrips che stampa i dati restituiti:

package main

import (
  "database/sql"
  "fmt"
  "strconv"
  "time"
)

func GetDBWithDSNPAT(dsn string) (*sql.DB, error) {
  db, err := sql.Open("databricks", dsn)
  if err != nil {
    return nil, err
  }
  return db, nil
}

func GetNYCTaxiTrips(db *sql.DB, numRows int) (*sql.Rows, error) {
  rows, err := db.Query("SELECT * FROM samples.nyctaxi.trips LIMIT " + strconv.Itoa(numRows))
  if err != nil {
    return nil, err
  }
  return rows, nil
}

func PrintNYCTaxiTrips(rows *sql.Rows) {
  var (
    tpep_pickup_datetime  time.Time
    tpep_dropoff_datetime time.Time
    trip_distance         float64
    fare_amount           float64
    pickup_zip            int
    dropoff_zip           int
  )

  fmt.Print(
    "tpep_pickup_datetime,",
    "tpep_dropoff_datetime,",
    "trip_distance,",
    "fare_amount,",
    "pickup_zip,",
    "dropoff_zip\n",
  )

  for rows.Next() {
    err := rows.Scan(
      &tpep_pickup_datetime,
      &tpep_dropoff_datetime,
      &trip_distance,
      &fare_amount,
      &pickup_zip,
      &dropoff_zip,
    )
    if err != nil {
      panic(err)
    }

    fmt.Print(
      tpep_pickup_datetime, ",",
      tpep_dropoff_datetime, ",",
      trip_distance, ",",
      fare_amount, ",",
      pickup_zip, ",",
      dropoff_zip, "\n",
    )
  }

  err := rows.Err()
  if err != nil {
    panic(err)
  }
}

E dato il file seguente denominato main.go che chiama queste funzioni:

package main

import (
  "os"
)

func main() {
  db, err := GetDBWithDSNPAT(os.Getenv("DATABRICKS_DSN"))
  if err != nil {
    panic(err)
  }

  rows, err := GetNYCTaxiTrips(db, 2)
  if err != nil {
    panic(err)
  }

  PrintNYCTaxiTrips(rows)
}

Il file seguente denominato helpers_test.go verifica se la funzione GetNYCTaxiTrips restituisce la risposta prevista. Anziché creare una connessione reale all'area di lavoro di destinazione, questo test simula un oggetto sql.DB. Il test simula anche alcuni dati conformi allo schema e ai valori presenti nei dati reali. Il test restituisce i dati fittizi tramite la connessione fittizia e quindi controlla se uno dei valori delle righe di dati fittizi corrisponde al valore previsto.

package main

import (
  "database/sql"
  "testing"

  "github.com/stretchr/testify/assert"
  "github.com/stretchr/testify/mock"
)

// Define an interface that contains a method with the same signature
// as the real GetNYCTaxiTrips function that you want to test.
type MockGetNYCTaxiTrips interface {
  GetNYCTaxiTrips(db *sql.DB, numRows int) (*sql.Rows, error)
}

// Define a struct that represents the receiver of the interface's method
// that you want to test.
type MockGetNYCTaxiTripsObj struct {
  mock.Mock
}

// Define the behavior of the interface's method that you want to test.
func (m *MockGetNYCTaxiTripsObj) GetNYCTaxiTrips(db *sql.DB, numRows int) (*sql.Rows, error) {
  args := m.Called(db, numRows)
  return args.Get(0).(*sql.Rows), args.Error(1)
}

func TestGetNYCTaxiTrips(t *testing.T) {
  // Instantiate the receiver.
  mockGetNYCTaxiTripsObj := new(MockGetNYCTaxiTripsObj)

  // Define how the mock function should be called and what it should return.
  // We're not concerned with whether the actual database is connected to--just
  // what is returned.
  mockGetNYCTaxiTripsObj.On("GetNYCTaxiTrips", mock.Anything, mock.AnythingOfType("int")).Return(&sql.Rows{}, nil)

  // Call the mock function that you want to test.
  rows, err := mockGetNYCTaxiTripsObj.GetNYCTaxiTrips(nil, 2)

  // Assert that the mock function was called as expected.
  mockGetNYCTaxiTripsObj.AssertExpectations(t)

  // Assert that the mock function returned what you expected.
  assert.NotNil(t, rows)
  assert.Nil(t, err)
}

Poiché la funzione GetNYCTaxiTrips contiene un'istruzione SELECT e pertanto non modifica lo stato della tabella trips, la simulazione non è assolutamente necessaria in questo esempio. Tuttavia, la simulazione consente di eseguire rapidamente i test senza attendere che venga stabilita una connessione effettiva con l'area di lavoro. Inoltre, la simulazione consente di eseguire test simulati più volte per le funzioni che potrebbero modificare lo stato di una tabella, ad esempio INSERT INTO, UPDATE e DELETE FROM.

Risorse aggiuntive