Partager via


Pilote SQL Databricks pour Go

Le pilote Databricks SQL pour Go est une bibliothèque Go qui vous permet d’utiliser du code Go pour exécuter des commandes SQL sur des ressources de calcul Azure Databricks. Cet article complète le pilote SQL Databricks pour Go README, la référence d’API et les exemples.

Spécifications

Bien démarrer avec le pilote SQL Databricks pour Go

  1. Sur un ordinateur de développement sur lequel vous avez déjà installé Go 1.20 ou version ultérieure et créé un projet de code Go, créez un fichier go.mod pour suivre les dépendances de votre code Go en exécutant la commande go mod init. Par exemple :

    go mod init sample
    
  2. Établissez une dépendance au package Pilote SQL Databricks pour Go en exécutant la commande go mod edit -require et en remplaçant v1.5.2 par la dernière version du package Pilote SQL Databricks pour Go, comme indiqué dans les notes de publication :

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

    Votre fichier go.mod doit maintenant ressembler à ceci :

    module sample
    
    go 1.20
    
    require github.com/databricks/databricks-sql-go v1.5.2
    
  3. Dans votre projet, créez un fichier de code Go qui importe le pilote SQL Databricks pour Go. L’exemple suivant, qui se trouve dans un fichier nommé main.go avec le contenu suivant, dresse la liste de tous les clusters de l’espace de travail 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. Ajoutez les dépendances de module manquantes en exécutant la commande go mod tidy :

    go mod tidy
    

    Remarque

    Si vous obtenez l’erreur go: warning: "all" matched no packages, cela signifie que vous avez oublié d’ajouter un fichier de code Go qui importe le pilote SQL Databricks pour Go.

  5. Faites des copies de tous les packages nécessaires pour prendre en charge les builds et les tests de packages dans votre module main. Pour cela, exécutez la commande go mod vendor :

    go mod vendor
    
  6. Modifiez votre code en fonction des besoins afin de définir la variable d’environnement DATABRICKS_DSN pour l’authentification Azure Databricks. Consultez également Se connecter avec une chaîne de connexion DSN.

  7. Exécutez votre fichier de code Go, en exécutant la commande go run dans l’hypothèse d’un fichier nommé main.go :

    go run main.go
    
  8. Si aucune erreur n’est retournée, vous avez correctement authentifié le pilote SQL Databricks pour Go auprès de votre espace de travail Azure Databricks et vous êtes connecté à votre cluster Azure Databricks en cours d’exécution ou à votre entrepôt SQL dans cet espace de travail.

Se connecter avec une chaîne de connexion DSN

Pour accéder aux clusters et aux entrepôts SQL, utilisez sql.Open() pour créer un handle de base de données via une chaîne de connexion DSN. Cet exemple de code récupère la chaîne de connexion DSN à partir d’une variable d’environnement appelée 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)
  }
}

Pour spécifier la chaîne de connexion DSN au bon format, consultez les exemples de chaîne de connexion DSN dans Authentification. Par exemple, pour l’authentification par jeton d’accès personnel Azure Databricks, utilisez la syntaxe suivante, où :

  • <personal-access-token> est votre jeton d’accès personnel Azure Databricks demandé dans les spécifications.
  • <server-hostname> est la valeur Nom d’hôte du serveur demandée dans les spécifications.
  • <port-number> est la valeur Port issue des exigences (en général, 443).
  • <http-path> est la valeur Chemin HTTP demandée dans les spécifications.
  • <paramX=valueX> correspond à un ou plusieurs paramètres facultatifs listés plus loin dans cet article.
token:<personal-access-token>@<server-hostname>:<port-number>/<http-path>?<param1=value1>&<param2=value2>

Par exemple, pour un cluster :

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

Par exemple, pour un entrepôt SQL :

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

Notes

En guise de bonne pratique de sécurité, ne codez pas en dur cette chaîne de connexion DSN dans votre code Go. Récupérez plutôt cette chaîne de connexion DSN à partir d’un emplacement sécurisé. Par exemple, le code plus haut dans cet article utilise une variable d’environnement.

Paramètres facultatifs

  • Vous pouvez spécifier les paramètres de connexion facultatifs pris en charge dans <param=value>. Voici quelques-uns des paramètres les plus fréquemment utilisés :
    • catalog : définit le nom du catalogue initial dans la session.
    • schema : définit le nom du schéma initial dans la session.
    • maxRows : configure le nombre maximal de lignes récupérées (fetch) par requête. Par défaut, il s’agit de 10000.
    • timeout : ajoute le délai d’attente (en secondes) pour l’exécution de la requête du serveur. Par défaut, il n’y a aucun délai d’attente.
    • userAgentEntry : utilisé pour identifier les partenaires. Pour plus d’informations, consultez la documentation de votre partenaire.
  • Vous pouvez spécifier les paramètres de session facultatifs pris en charge dans param=value. Voici quelques-uns des paramètres les plus fréquemment utilisés :
    • ansi_mode : chaîne de type Boolean. true pour que les instructions de session respectent les règles spécifiées par la spécification SQL ANSI. La valeur système par défaut est false.
    • timezone : chaîne, par exemple America/Los_Angeles. Définit le fuseau horaire de la session. La valeur système par défaut est UTC.

Par exemple, pour un entrepôt SQL :

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

Se connecter avec la fonction NewConnector

Vous pouvez également utiliser sql.OpenDB() pour créer un handle de base de données via un nouvel objet de connecteur créé avec dbsql.NewConnector() (la connexion aux clusters Azure Databricks et aux entrepôts SQL avec un nouvel objet de connecteur nécessite la version 1.0.0 ou ultérieure du pilote Databricks SQL pour Go). Par exemple :

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

Pour spécifier l’ensemble correct de paramètres NewConnector, consultez les exemples dans Authentification.

Remarque

En guise de bonne pratique de sécurité, ne codez pas en dur vos paramètres NewConnector dans votre code Go. Au lieu de cela, vous devez récupérer ces valeurs à partir d’un emplacement sécurisé. Par exemple, le code précédent utilise des variables d’environnement.

Voici quelques-unes des options fonctionnelles les plus fréquemment utilisées :

  • WithAccessToken(<access-token>) : votre jeton d’accès personnel Azure Databricks issu des exigences. string obligatoire.
  • WithServerHostname(<server-hostname>) : valeur Nom d’hôte du serveur issue des exigences. string obligatoire.
  • WithPort(<port>) : numéro de port du serveur, généralement 443. int obligatoire.
  • WithHTTPPath(<http-path>) : valeur Chemin HTTP issue des exigences. string obligatoire.
  • WithInitialNamespace(<catalog>, <schema>) : nom du catalogue et du schéma dans la session. Facultatifstring, string.
  • WithMaxRows(<max-rows>) : nombre maximal de lignes récupérées (fetch) par requête. La valeur par défaut est 10000. int facultatif.
  • WithSessionParams(<params-map>) : paramètres de session incluant « timezone » et « ansi_mode ». Facultatifmap[string]string.
  • WithTimeout(<timeout>). Délai d’expiration (en time.Duration) pour l’exécution de la requête du serveur. Par défaut, il n’y a aucun délai d’attente. facultatif.
  • WithUserAgentEntry(<isv-name-plus-product-name>). Utilisé pour identifier les partenaires. Pour plus d’informations, consultez la documentation de votre partenaire. Facultatifstring.

Par exemple :

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"),
)

Authentification

Le pilote SQL Databricks pour Go prend en charge les types d’authentification Azure Databricks suivants :

Le pilote SQL Databricks pour Go ne prend pas encore en charge les types d’authentification Azure Databricks suivants :

Authentification par jeton d’accès personnel Databricks

Pour utiliser le pilote SQL Databricks pour Go avec l’authentification par jeton d’accès personnel Azure Databricks, vous devez d’abord créer un jeton d’accès personnel Azure Databricks de la façon suivante :

  1. Dans votre espace de travail Azure Databricks, cliquez sur votre nom d’utilisateur Azure Databricks dans la barre supérieure, puis sélectionnez Paramètres dans la liste déroulante.
  2. Cliquez sur Développeur.
  3. À côté de Jetons d’accès, cliquez sur Gérer.
  4. Cliquez sur Générer un nouveau jeton.
  5. (Facultatif) Entrez un commentaire qui vous aide à identifier ce jeton à l’avenir et modifiez sa durée de vie par défaut (90 jours). Pour créer un jeton sans durée de vie (non recommandé), laissez vide la zone Durée de vie (en jours).
  6. Cliquez sur Générer.
  7. Copiez le jeton affiché dans un emplacement sécurisé, puis cliquez sur Terminé.

Remarque

Veillez à enregistrer le jeton copié dans un emplacement sécurisé. Ne partagez pas votre jeton copié avec d'autres. Si vous le perdez, vous ne pouvez pas régénérer exactement le même. Vous devez donc répéter cette procédure pour créer un jeton. Si vous perdez le jeton copié ou si vous pensez que le jeton a été compromis, Databricks vous recommande vivement de supprimer immédiatement ce jeton de votre espace de travail en cliquant sur l’icône de la corbeille (Révoquer) à côté du jeton de la page Jetons d’accès.

Si vous n'êtes pas en mesure de créer ou d'utiliser des jetons dans votre espace de travail, cela peut être dû au fait que votre administrateur d'espace de travail a désactivé les jetons ou ne vous a pas donné l'autorisation de créer ou d'utiliser des jetons. Consultez votre administrateur d'espace de travail ou les rubriques suivantes :

Pour authentifier le pilote SQL Databricks pour Go avec une chaîne de connexion DSN et l’exemple de code dans Se connecter avec une chaîne de connexion DSN, utilisez la syntaxe de chaîne de connexion DSN suivante, où :

  • <personal-access-token> est votre jeton d’accès personnel Azure Databricks demandé dans les spécifications.
  • <server-hostname> est la valeur Nom d’hôte du serveur demandée dans les spécifications.
  • <port-number> est la valeur Port issue des exigences (en général, 443).
  • <http-path> est la valeur Chemin HTTP demandée dans les spécifications.

Vous pouvez également ajouter un ou plusieurs paramètres facultatifs répertoriés précédemment dans cet article.

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

Pour authentifier le pilote SQL Databricks pour Go avec la fonction NewConnector, utilisez l’extrait de code suivant et l’exemple de code dans Se connecter avec la fonction NewConnector, ce qui suppose que vous avez défini les variables d’environnement suivantes :

  • DATABRICKS_SERVER_HOSTNAME réglé sur la valeur Nom d'hôte de serveur de votre cluster ou entrepôt SQL.
  • DATABRICKS_HTTP_PATH, réglé sur la valeur Chemin HTTP de votre cluster ou entrepôt SQL.
  • DATABRICKS_TOKEN, réglé sur le jeton d’accès personnel Azure Databricks.

Pour définir des variables d’environnement, consultez la documentation de votre système d’exploitation.

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")),
)

Authentification par jeton Microsoft Entra ID

Le pilote SQL Databricks pour Go prend en charge les jetons Microsoft Entra ID pour un utilisateur Azure Databricks ou un principal de service Microsoft Entra ID.

Pour créer un jeton d’accès Microsoft Entra ID, effectuez ce qui suit :

  • Vous pouvez utiliser l’interface utilisateur Azure CLI pour un utilisateur Azure Databricks. Consultez Obtenir des jetons Microsoft Entra ID pour les utilisateurs avec Azure CLI.

    Les jetons Microsoft Entra ID ont une durée de vie par défaut d’environ une heure. Pour créer un jeton Microsoft Entra ID, répétez ce processus.

    Pour authentifier le pilote SQL Databricks pour Go avec une chaîne de connexion DSN et l’exemple de code dans Se connecter avec une chaîne de connexion DSN, utilisez la syntaxe de chaîne de connexion DSN suivante, où :

    • <microsoft-entra-id-token> est votre jeton Microsoft Entra ID.
    • <server-hostname> est la valeur Nom d’hôte du serveur demandée dans les spécifications.
    • <port-number> est la valeur Port issue des exigences (en général, 443).
    • <http-path> est la valeur Chemin HTTP demandée dans les spécifications.

    Vous pouvez également ajouter un ou plusieurs paramètres facultatifs répertoriés précédemment dans cet article.

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

    Pour authentifier le pilote SQL Databricks pour Go avec la fonction NewConnector, utilisez l’extrait de code suivant et l’exemple de code dans Se connecter avec la fonction NewConnector, ce qui suppose que vous avez défini les variables d’environnement suivantes :

    • DATABRICKS_SERVER_HOSTNAME réglé sur la valeur Nom d'hôte de serveur de votre cluster ou entrepôt SQL.
    • DATABRICKS_HTTP_PATH, réglé sur la valeur Chemin HTTP de votre cluster ou entrepôt SQL.
    • DATABRICKS_TOKEN, définie sur votre jeton Microsoft Entra ID.

    Pour définir des variables d’environnement, consultez la documentation de votre système d’exploitation.

    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")),
    )
    

Authentification utilisateur à machine (U2M) OAuth

Les versions 1.5.0 et ultérieures du pilote SQL Databricks pour Go prennent en charge l’authentification utilisateur-à-machine (U2M) OAuth.

Pour utiliser le pilote SQL Databricks pour Go avec une chaîne de connexion DSN et l’exemple de code dans Se connecter avec une chaîne de connexion DSN, utilisez la syntaxe de chaîne de connexion DSN suivante, où :

  • <server-hostname> est la valeur Nom d’hôte du serveur demandée dans les spécifications.
  • <port-number> est la valeur Port issue des exigences (en général, 443).
  • <http-path> est la valeur Chemin HTTP demandée dans les spécifications.

Vous pouvez également ajouter un ou plusieurs paramètres facultatifs répertoriés précédemment dans cet article.

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

Pour authentifier le pilote SQL Databricks pour Go avec la fonction NewConnector, vous devez d’abord ajouter ce qui suit à votre déclaration import :

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

Utilisez ensuite l’extrait de code suivant et l’exemple de code dans Se connecter avec la fonction NewConnector, ce qui suppose que vous avez défini les variables d’environnement suivantes :

  • DATABRICKS_SERVER_HOSTNAME réglé sur la valeur Nom d'hôte de serveur de votre cluster ou entrepôt SQL.
  • DATABRICKS_HTTP_PATH, réglé sur la valeur Chemin HTTP de votre cluster ou entrepôt SQL.

Pour définir des variables d’environnement, consultez la documentation de votre système d’exploitation.

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),
)

Authentification OAuth machine à machine (M2M)

Les versions 1.5.2 et ultérieures du pilote SQL Databricks pour Go prennent en charge l’authentification machine-à-machine (M2M) OAuth.

Pour utiliser le pilote SQL Databricks pour Go avec l’authentification M2M OAuth, vous devez effectuer les opérations suivantes :

  1. Créez un principal de service Azure Databricks dans votre espace de travail Azure Databricks et créez un secret OAuth pour ce principal de service.

    Pour créer le principal de service et son secret OAuth, consultez Authentifier l’accès à Azure Databricks avec un principal de service à l’aide d’OAuth (OAuth M2M). Notez la valeur de l’UUID ou de l’ID de l’application du principal de service, ainsi que la valeur du secret OAuth du principal de service.

  2. Accordez à ce principal de service l’accès à votre cluster ou entrepôt.

    Pour accorder au principal de service l’accès à votre cluster ou entrepôt, consultez Autorisations de calcul ou Gérer un entrepôt SQL.

Pour authentifier le pilote SQL Databricks pour Go avec une chaîne de connexion DSN et l’exemple de code dans Se connecter avec une chaîne de connexion DSN, utilisez la syntaxe de chaîne de connexion DSN suivante, où :

  • <server-hostname> est la valeur Nom d’hôte du serveur demandée dans les spécifications.
  • <port-number> est la valeur Port issue des exigences (en général, 443).
  • <http-path> est la valeur Chemin HTTP demandée dans les spécifications.
  • <client-id> est la valeur de l’UUID ou de l’ID de l’application du principal de service.
  • <client-secret> est la valeur Secret du secret OAuth du principal de service.

Vous pouvez également ajouter un ou plusieurs paramètres facultatifs répertoriés précédemment dans cet article.

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

Pour authentifier le pilote SQL Databricks pour Go avec la fonction NewConnector, vous devez d’abord ajouter ce qui suit à votre déclaration import :

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

Utilisez ensuite l’extrait de code suivant et l’exemple de code dans Se connecter avec la fonction NewConnector, ce qui suppose que vous avez défini les variables d’environnement suivantes :

  • DATABRICKS_SERVER_HOSTNAME réglé sur la valeur Nom d'hôte de serveur de votre cluster ou entrepôt SQL.
  • DATABRICKS_HTTP_PATH, réglé sur la valeur Chemin HTTP de votre cluster ou entrepôt SQL.
  • DATABRICKS_CLIENT_ID, est fixé à la valeur de l’UUID ou de l’ID de l’application du principal de service.
  • DATABRICKS_CLIENT_SECRET, définie sur la valeur Secret du secret OAuth du principal de service.

Pour définir des variables d’environnement, consultez la documentation de votre système d’exploitation.

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),
)

Interroger des données

L’exemple de code suivant montre comment appeler le pilote Databricks SQL pour Go afin d’exécuter une requête SQL de base sur une ressource de calcul Azure Databricks. Cette commande retourne les deux premières lignes de la table trips dans le schéma nyctaxi du catalogue samples.

Cet exemple de code récupère la chaîne de connexion DSN à partir d’une variable d’environnement appelée 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)
  }
}

Gérer les fichiers dans les volumes de catalogue Unity

Databricks SQL Driver vous permet d’écrire des fichiers locaux dans des volumesdu catalogue Unity, de télécharger des fichiers à partir de volumes et de supprimer des fichiers des volumes, comme illustré dans l’exemple suivant :

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

Logging

Utilisez github.com/databricks/databricks-sql-go/logger pour consigner les messages émis par le pilote SQL Databricks pour Go. L’exemple de code suivant utilise sql.Open() pour créer un descripteur de base de données par une chaîne de connexion DSN. Cet exemple de code récupère la chaîne de connexion DSN à partir d’une variable d’environnement appelée DATABRICKS_DSN. Tous les messages de journal émis au niveau debug (et les niveaux inférieurs) sont écrits dans le fichier 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

Pour tester votre code, utilisez des infrastructures de test Go tels que la bibliothèque standard de test. Pour tester votre code dans des conditions simulées sans appeler des points de terminaison d’API REST d'Azure Databricks ni modifier l’état de vos comptes ou espaces de travail Azure Databricks, utilisez des bibliothèques fictives Go telles que testfify.

Par exemple, étant donné le fichier suivant nommé helpers.go contenant une fonction GetDBWithDSNPAT qui retourne une connexion d’espace de travail Azure Databricks, une fonction GetNYCTaxiTrips qui retourne des données de la table trips dans le schéma samples du catalogue nyctaxi et un PrintNYCTaxiTrips qui imprime les données retournées :

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

Et compte tenu du fichier suivant nommé main.go qui appelle ces fonctions :

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

Le fichier suivant nommé helpers_test.go teste si la fonction GetNYCTaxiTrips retourne la réponse attendue. Au lieu de créer une connexion réelle à l’espace de travail cible, ce test simule un objet sql.DB. Le test simule également des données qui sont conformes au schéma et aux valeurs qui se trouvent dans les données réelles. Le test renvoie les données simulées sur la connexion simulée, puis vérifie si une des valeurs des lignes de données simulées correspond à la valeur attendue.

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

Étant donné que la fonction GetNYCTaxiTrips contient une instruction SELECT et ne modifie donc pas l’état de la table trips, la simulation n’est pas absolument nécessaire dans cet exemple. Toutefois, la simulation vous permet d’exécuter rapidement vos tests sans attendre qu’une connexion réelle soit établie avec l’espace de travail. En outre, la simulation vous permet d’exécuter des tests simulés plusieurs fois pour les fonctions susceptibles de modifier l’état d’une table, comme INSERT INTO, UPDATEet DELETE FROM.

Ressources supplémentaires