Aller au contenu principal

Driver Databricks SQL pour Go

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

Exigences

Démarrer avec le Driver Databricks SQL pour Go.

  1. Sur votre machine de développement avec Go 1.20 ou version supérieure déjà installé et un projet de code Go existant déjà créé, 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 :

    Bash
    go mod init sample
  2. Prenez une dépendance vis-à-vis du package Databricks SQL Driver pour Go en exécutant la commande go mod edit -require, en remplaçant v1.5.2 par la dernière version du package Databricks SQL Driver pour Go, telle qu’indiquée dans les versions:

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

    Votre fichier go.mod devrait maintenant ressembler à ceci :

    Go
    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 Driver Databricks SQL pour Go. L'exemple suivant, dans un fichier nommé main.go avec le contenu suivant, répertorie tous les clusters de votre workspace Databricks :

    Go
    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 toutes les dépendances de module manquantes en exécutant la commande go mod tidy :

    Bash
    go mod tidy
remarque

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

  1. Faites des copies de tous les packages nécessaires pour prendre en charge les compilations et les tests de packages dans votre module main, en exécutant la commande go mod vendor :

    Bash
    go mod vendor
  2. Modifiez votre code si nécessaire pour définir la variable d'environnement DATABRICKS_DSN pour l'authentification Databricks. Voir aussi Connecter avec une chaîne de connexion DSN.

  3. Exécutez votre fichier de code Go, en supposant un fichier nommé main.go, en exécutant la commande go run :

    Bash
    go run main.go
  4. Si aucune erreur n'est renvoyée, vous avez authentifié avec succès le Databricks SQL Driver pour Go avec votre Databricks Workspace et vous vous êtes connecté à votre cluster Databricks ou SQL Warehouse en cours d'exécution dans ce Workspace.

Connectez-vous avec une chaîne de connexion DSN

Pour accéder aux clusters et aux SQL Warehouses, utilisez sql.Open() pour créer un descripteur de base de données via une chaîne de connexion de nom de source de données (DSN). Cet exemple de code récupère la chaîne de connexion DSN à partir d'une variable d'environnement nommée DATABRICKS_DSN:

Go
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 format correct, consultez les exemples de chaînes de connexion DSN dans Authentification. Par exemple, pour l'authentification par jeton d'accès personnel Databricks, utilisez la syntaxe suivante, où :

  • <personal-access-token> est votre jeton d'accès personnel Databricks des exigences.
  • <server-hostname> est la valeur **Hostname du serveur** des exigences.
  • <port-number> est la valeur Port des exigences, qui est généralement 443.
  • <http-path> est la valeur du Chemin HTTP à partir des exigences.
  • <paramX=valueX> est un ou plusieurs paramètres facultatifs répertoriés plus loin dans cet article.
token:<personal-access-token>@<server-hostname>:<port-number>/<http-path>?<param1=value1>&

Par exemple, pour un cluster :

token:dapi12345678901234567890123456789012@dbc-a1b2345c-d6e7.cloud.databricks.com:443/sql/protocolv1/o/1234567890123456/1234-567890-abcdefgh

Par exemple, pour un SQL Warehouse :

token:dapi12345678901234567890123456789012@dbc-a1b2345c-d6e7.cloud.databricks.com:443/sql/1.0/endpoints/a1b234c5678901d2
remarque

Pour des raisons de sécurité, vous ne devez pas coder en dur cette chaîne de connexion DSN dans votre code Go. Au lieu de cela, vous devez récupérer cette chaîne de connexion DSN à partir d'un emplacement sécurisé. Par exemple, l'exemple de code précédent dans cet article utilisait une variable d'environnement.

Parameters facultatifs

  • Les paramètres de connexion facultatifs pris en charge peuvent être spécifiés dans <param=value>. Parmi les plus fréquemment utilisés, on trouve :

    • catalog: Définit le nom de catalogue initial dans la session.
    • schema: Définit le nom de schéma initial dans la session.
    • maxRows: définit le nombre maximal de lignes récupérées par requête. La default est 10000.
    • timeout: Ajoute le délai d'expiration (en secondes) pour l'exécution de la query du serveur. default, il n'y a pas de délai d'expiration.
    • userAgentEntry: Sert à identifier les Partenaires. Pour plus d'informations, consultez la documentation de votre partenaire.
  • Les paramètres de session facultatifs pris en charge peuvent être spécifiés dans param=value. Parmi les plus fréquemment utilisés, on trouve :

    • ansi_mode: Une chaîne booléenne. true pour que les déclarations de session adhèrent aux règles spécifiées par la spécification ANSI SQL. La valeur par default du système est false.
    • timezone: Une chaîne, par exemple America/Los_Angeles. Définit le fuseau horaire de la session. La valeur default du système est UTC.
    • query_tags: chaîne de clés séparées par des virgules paires à joindre aux requêtes SQL pour le suivi dans system.query.history, par exemple team:engineering,dashboard:abc123. Cette fonctionnalité est en Aperçu public.

Par exemple, pour un SQL Warehouse :

token:dapi12345678901234567890123456789012@dbc-a1b2345c-d6e7.cloud.databricks.com:443/sql/1.0/endpoints/a1b234c5678901d2?catalog=hive_metastore&schema=example&maxRows=100&timeout=60&timezone=America/Sao_Paulo&ansi_mode=true&query_tags=team:engineering,env:prod

Connectez-vous à la fonction NewConnector

Vous pouvez également utiliser sql.OpenDB() pour créer un descripteur de base de données via un nouvel objet connecteur créé avec dbsql.NewConnector() (la connexion aux clusters et SQL Warehouses Databricks avec un nouvel objet connecteur nécessite la version 1.0.0 ou supérieure du Driver Databricks SQL pour Go). Par exemple :

Go
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

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

Certaines des options fonctionnelles les plus fréquemment utilisées incluent :

  • WithAccessToken(<access-token>): Votre jeton d'accès personnel Databricks issu des exigences. Obligatoire string.
  • WithServerHostname(<server-hostname>): La valeur Hostname du serveur des exigences. Requis string.
  • WithPort(<port>): Le numéro de port du serveur, généralement 443. Requis int.
  • WithHTTPPath(<http-path>): La valeur du **chemin HTTP** issue des exigences. Requis string.
  • WithInitialNamespace(<catalog>, <schema>) nom du catalogue et du schéma dans la session. string, string (facultatif).
  • WithMaxRows(<max-rows>): Le nombre maximal de lignes récupérées par requête. La valeur par default est 10000. facultative int.
  • WithSessionParams(<params-map>): Les paramètres de session incluent « timezone », « ansi_mode » et « query_tags ». map[string]string (facultatif).
  • WithTimeout(<timeout>)Le délai d'expiration (en time.Duration) pour l'exécution de la query serveur. Par default, aucun délai d'expiration n'est défini. Facultatif.
  • WithUserAgentEntry(<isv-name-plus-product-name>). Permet d'identifier les Partenaires. Pour plus d'informations, consultez la documentation de votre partenaire. Facultatif string.

Par exemple :

Go
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", "query_tags": "team:analytics,project:reporting"}),
dbsql.WithTimeout(time.Minute),
dbsql.WithUserAgentEntry("example-user"),
)

Authentification

Le Driver Databricks SQL pour Go prend en charge les types d'authentification Databricks suivants :

Authentification par jeton d'accès personnel Databricks

Pour utiliser le Driver Databricks SQL pour Go avec l'authentification par jeton d'accès personnel Databricks, vous devez d'abord créer un jeton d'accès personnel Databricks. Pour plus de détails sur cette étape, consultez Créer des jetons d'accès personnels pour les utilisateurs du Workspace.

Pour authentifier le Driver Databricks SQL 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 :

  • <personal-access-token> est votre jeton d'accès personnel Databricks des exigences.
  • <server-hostname> est la valeur **Hostname du serveur** des exigences.
  • <port-number> est la valeur Port des exigences, qui est généralement 443.
  • <http-path> est la valeur du Chemin HTTP à partir des exigences.

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

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

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

  • DATABRICKS_SERVER_HOSTNAMEdéfini sur la valeur **Hostname du serveur** de votre cluster ou SQL Warehouse.
  • DATABRICKS_HTTP_PATH, défini sur la valeur Chemin HTTP pour votre cluster ou SQL Warehouse.
  • DATABRICKS_TOKEN, défini sur le jeton d'accès personnel Databricks.

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

Go
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 OAuth d'utilisateur à machine (U2M)

Le Driver Databricks SQL pour Go versions 1.5.0 et ultérieures prend en charge l'authentification OAuth utilisateur-à-machine (U2M).

Pour utiliser le Driver Databricks SQL 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 **Hostname du serveur** des exigences.
  • <port-number> est la valeur Port des exigences, qui est généralement 443.
  • <http-path> est la valeur du Chemin HTTP à partir des exigences.

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

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

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

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

Ensuite, utilisez l'extrait de code suivant et l'exemple de code dans Connectez-vous avec la fonction NewConnector, qui suppose que vous avez défini les variables d'environnement suivantes :

  • DATABRICKS_SERVER_HOSTNAMEdéfini sur la valeur **Hostname du serveur** de votre cluster ou SQL Warehouse.
  • DATABRICKS_HTTP_PATH, défini sur la valeur Chemin HTTP pour votre cluster ou SQL Warehouse.

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

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

Databricks SQL Driver pour Go versions 1.5.2 et ultérieures prennent en charge l'authentification OAuth machine à machine (M2M).

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

  1. Créez un Service Principal Databricks dans votre Workspace Databricks, et créez un secret OAuth pour ce Service Principal.

    Pour créer le service principal et son secret OAuth, consultez Autoriser l'accès du service principal à Databricks avec OAuth. Notez la valeur du **UUID** ou de l'**ID d'application** du service principal, ainsi que la valeur du **Secret** du secret OAuth du service principal.

  2. Donnez à ce Service Principal l'accès à votre cluster ou warehouse.

    Pour donner au Service Principal l'accès à votre cluster ou warehouse, consultez Autorisations de compute ou Gérer un SQL Warehouse.

Pour authentifier le Driver Databricks SQL 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 :

  • <server-hostname> est la valeur **Hostname du serveur** des exigences.
  • <port-number> est la valeur Port des exigences, qui est généralement 443.
  • <http-path> est la valeur du Chemin HTTP à partir des exigences.
  • <client-id> valeur de l'**UUID** ou de l'**ID de l'application** du service principal.
  • <client-secret> est la valeur Secrète pour le secret OAuth du Service Principal.

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

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

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

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

Ensuite, utilisez l'extrait de code suivant et l'exemple de code dans Connectez-vous avec la fonction NewConnector, qui suppose que vous avez défini les variables d'environnement suivantes :

  • DATABRICKS_SERVER_HOSTNAMEdéfini sur la valeur **Hostname du serveur** de votre cluster ou SQL Warehouse.
  • DATABRICKS_HTTP_PATH, défini sur la valeur Chemin HTTP pour votre cluster ou SQL Warehouse.
  • DATABRICKS_CLIENT_ID, défini sur la valeur **UUID** ou **ID d'Application** du Service Principal.
  • DATABRICKS_CLIENT_SECRET, défini sur la valeur **Secret** du secret OAuth du Service Principal.

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

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

Query des données

L'exemple de code suivant montre comment appeler le Driver Databricks SQL pour Go pour exécuter une query SQL de base sur une ressource de compute Databricks. Cette commande renvoie 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 nommée DATABRICKS_DSN.

Go
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 Unity Catalog

Le Driver Databricks SQL vous permet d'écrire des fichiers locaux dans les volumes Unity Catalog, de download des fichiers depuis des volumes et de supprimer des fichiers des volumes, comme le montre l'exemple suivant :

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

Journalisation

Utilisez github.com/databricks/databricks-sql-go/logger pour log les messages émis par le Driver Databricks SQL pour Go. L'exemple de code suivant utilise sql.Open() pour créer un gestionnaire 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 nommée DATABRICKS_DSN. Tous les messages de log qui sont émis au niveau debug et en dessous sont écrits dans le fichier results.log.

Go
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 frameworks de test Go tels que la bibliothèque standard de tests. Pour tester votre code dans des conditions simulées sans appeler les Endpoint de l'API REST Databricks ou modifier l'état de vos comptes ou Workspace Databricks, utilisez des bibliothèques de simulation Go telles que testfify.

Par exemple, étant donné le fichier suivant nommé helpers.go contenant une fonction GetDBWithDSNPAT qui renvoie une connexion au Workspace Databricks, une fonction GetNYCTaxiTrips qui renvoie des données de la table trips dans le schéma nyctaxi du catalogue samples, et une PrintNYCTaxiTrips qui affiche les données renvoyées :

Go
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 ?", 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 étant donné le fichier suivant nommé main.go qui appelle ces fonctions :

Go
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 renvoie la réponse attendue. Plutôt que de créer une connexion réelle au Workspace cible, ce test simule un objet sql.DB. Le test simule également des données qui sont conformes au schéma et aux valeurs présentes dans les données réelles. Le test renvoie les données mockées via la connexion mockée, puis vérifie si l'une des valeurs des lignes de données mockées correspond à la valeur attendue.

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

Parce 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 requise dans cet exemple. Cependant, le mocking vous permet d'exécuter rapidement vos tests sans attendre qu'une connexion réelle soit établie avec le workspace. De plus, la simulation vous permet d'exécuter des tests simulés plusieurs fois pour les fonctions qui pourraient modifier l'état d'une table, comme INSERT INTO, UPDATE et DELETE FROM.

Ressources supplémentaires