Freigeben über


Databricks SQL-Treiber für Go

Der Databricks SQL-Treiber für Go ist eine Go-Bibliothek, mit der Sie den Go-Code verwenden können, um SQL-Befehle für Azure Databricks-Computeressourcen auszuführen. Dieser Artikel ergänzt das Databricks SDK-Treiber für Go README, die zugehörige API-Referenz und entsprechende Beispiele.

Anforderungen

Erste Schritte mit dem Databricks-SQL-Treiber für Go

  1. Erstellen Sie auf Ihrem Entwicklungscomputer, auf dem bereits Go 1.20 oder höher installiert und ein Go-Codeprojekt erstellt eine Datei go.mod, um die Abhängigkeiten Ihres Go-Codes nachzuverfolgen. Führen Sie dazu den Befehl go mod init wie im folgenden Beispiel aus:

    go mod init sample
    
  2. Erstellen Sie eine Abhängigkeit vom Databricks-SQL-Treiber für Go-Paket, indem Sie den Befehl go mod edit -require ausführen und v1.5.2 durch die neueste Version des Databricks-SQL-Treiber für Go-Pakets ersetzen, wie unter Releases aufgeführt:

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

    Die Datei go.mod sollte jetzt wie folgt aussehen:

    module sample
    
    go 1.20
    
    require github.com/databricks/databricks-sql-go v1.5.2
    
  3. Erstellen Sie in Ihrem Projekt eine Go-Codedatei, die den Databricks-SQL-Treiber für Go importiert. Im folgenden Beispiel werden in der Datei mit Namen main.go mit folgendem Inhalt alle Cluster in Ihrem Azure Databricks-Arbeitsbereich aufgelistet:

    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. Fügen Sie alle fehlenden Modulabhängigkeiten hinzu, indem Sie den Befehl go mod tidy ausführen:

    go mod tidy
    

    Hinweis

    Wenn Sie den Fehler go: warning: "all" matched no packages erhalten, haben Sie vergessen, eine Go-Codedatei hinzuzufügen, die den Databricks-SQL-Treiber für Go importiert.

  5. Erstellen Sie Kopien aller Pakete, die zur Unterstützung von Builds und Tests der Pakete in Ihrem main-Modul benötigt werden, indem Sie den Befehl go mod vendor ausführen:

    go mod vendor
    
  6. Ändern Sie Ihren Code nach Bedarf, um die Umgebungsvariable DATABRICKS_DSN für die Azure Databricks-Authentifizierung festzulegen. Weitere Informationen finden Sie unter Herstellen einer Verbindung mit einer DSN-Verbindungszeichenfolge.

  7. Führen Sie Ihre Go-Codedatei aus, wobei Sie von einer Datei namens main.go ausgehen, indem Sie den Befehl go run ausführen:

    go run main.go
    
  8. Wenn keine Fehler zurückgegeben werden, haben Sie den Databricks-SQL-Treiber für Go erfolgreich in Ihrem Azure Databricks-Arbeitsbereich authentifiziert und mit Ihrem ausgeführten Azure Databricks-Cluster oder SQL-Warehouse in diesem Arbeitsbereich verbunden.

Herstellen einer Verbindung mit einer DSN-Verbindungszeichenfolge

Verwenden Sie sql.Open() für den Zugriff auf Cluster und SQL-Warehouses, um ein Datenbankhandle über eine Datenquellenname-Verbindungszeichenfolge (Data Source Name, DSN) zu erstellen. In diesem Codebeispiel wird die DSN-Verbindungszeichenfolge aus einer Umgebungsvariablen namens DATABRICKS_DSN abgerufen:

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

Informationen zum Angeben der DSN-Verbindungszeichenfolge im richtigen Format finden Sie in den Beispielen für DSN-Verbindungszeichenfolgen unter Authentifizierung. Verwenden Sie z. B. für die Authentifizierung mit einem persönlichen Azure Databricks-Zugriffstoken die folgende Syntax, für die Folgendes gilt:

  • <personal-access-token> ist das persönliches Zugriffstoken für Azure Databricks aus den Anforderungen.
  • <server-hostname> ist der Serverhostname-Wert aus den Anforderungen.
  • <port-number> ist der Portwert aus den Anforderungen, der in der Regel 443 ist.
  • <http-path> ist der HTTP-Pfad-Wert aus den Anforderungen.
  • <paramX=valueX> ist mindestens ein optionaler Parameter, der weiter unten in diesem Artikel aufgeführt wird.
token:<personal-access-token>@<server-hostname>:<port-number>/<http-path>?<param1=value1>&<param2=value2>

Zum Beispiel für einen Cluster:

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

Beispiel für ein SQL-Warehouse:

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

Hinweis

Aus Sicherheitsgründen sollten Sie diese DSN-Zeichenfolgenverbindung nicht in Ihren Go-Code hartcodieren. Stattdessen sollten Sie diese DSN-Verbindung von einem sicheren Speicherort abrufen. Im Codebeispiel weiter oben in diesem Artikel wurde beispielsweise eine Umgebungsvariable verwendet.

Optionale Parameter

  • Unterstützte optionale Verbindungsparameter können in <param=value> angegeben werden. Zu den häufiger verwendeten gehören:
    • catalog: Legt den anfänglichen Katalognamen in der Sitzung fest.
    • schema: Legt den anfänglichen Schemanamen in der Sitzung fest.
    • maxRows: Richtet die maximale Anzahl von Zeilen ein, die pro Anforderung abgerufen werden. Der Standardwert lautet 10000.
    • timeout: Fügt das Timeout (in Sekunden) für die Serverabfrageausführung hinzu. Der Standardwert ist kein Timeout.
    • userAgentEntry: Wird verwendet, um Partner zu identifizieren. Weitere Informationen finden Sie in der Dokumentation Ihres Partners.
  • Unterstützte optionale Sitzungsparameter können in param=value angegeben werden. Zu den häufiger verwendeten gehören:
    • ansi_mode: Eine Boolesche Zeichenfolge. true, damit Sitzungsanweisungen die in der ANSI-SQL-Spezifikation festgelegten Regeln einhalten. Die Systemstandardeinstellung ist FALSE.
    • America/Los_Angeles: Eine Zeichenfolge, z. B. timezone. Legt die Zeitzone der Sitzung fest. Die Systemstandardeinstellung ist UTC.

Beispiel für ein 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

Herstellen einer Verbindung mit der NewConnector-Funktion

Alternativ können Sie sql.OpenDB() verwenden, um ein Datenbankhandle über ein neues Connectorobjekt zu erstellen, das mit dbsql.NewConnector() erstellt wird (für das Herstellen einer Verbindung mit Azure Databricks-Clustern und SQL-Warehouses mit einem neuen Connectorobjekt ist v1.0.0 oder höher des Databricks SQL-Treibers für Go erforderlich). Beispiel:

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

Informationen zum Angeben der richtigen NewConnector-Einstellungen finden Sie in den Beispielen unter Authentifizierung.

Hinweis

Als bewährte Methode für die Sicherheit sollten Sie Ihre NewConnector-Einstellungen nicht in Ihrem Go-Code hartcodieren. Stattdessen sollten Sie diese Werte von einem sicheren Ort abrufen. Im vorherigen Code werden beispielsweise Umgebungsvariablen verwendet.

Zu den häufiger verwendeten funktionalen Optionen gehören:

  • WithAccessToken(<access-token>): Ihr persönliches Azure Databricks-Zugriffstoken aus den Anforderungen. Erforderlich: string
  • WithServerHostname(<server-hostname>): Der Wert des Serverhostnamens aus den Anforderungen. Erforderlich: string
  • WithPort(<port>): Die Portnummer des Servers, in der Regel 443. Erforderlich: int
  • WithHTTPPath(<http-path>): Der Wert des HTTP-Pfads aus den Anforderungen. Erforderlich: string
  • WithInitialNamespace(<catalog>, <schema>):Der Katalog- und Schemaname in der Sitzung. Optionalstring, string.
  • WithMaxRows(<max-rows>): Die maximale Anzahl von Zeilen, die pro Anforderung abgerufen werden. Standardwert: 10000. Optional: int
  • WithSessionParams(<params-map>): Die Sitzungsparameter, einschließlich „timezone“ und „ansi_mode“. Optionalmap[string]string.
  • WithTimeout(<timeout>). Das Timeout (in time.Duration) für die Serverabfrageausführung. Der Standardwert ist kein Timeout. Optional.
  • WithUserAgentEntry(<isv-name-plus-product-name>). Wird verwendet, um Partner zu identifizieren. Weitere Informationen finden Sie in der Dokumentation Ihres Partners. Optionalstring.

Beispiel:

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

Authentifizierung

Der Databricks-SQL-Treiber für Go unterstützt die folgenden Azure Databricks-Authentifizierungstypen:

Der Databricks SQL-Treiber für Go unterstützt noch nicht die folgenden Azure Databricks-Authentifizierungstypen:

Authentifizierung mit persönlichen Databricks-Zugriffstoken

Um den Databricks SQL-Treiber für Go mit der Authentifizierung des persönlichen Zugriffstokens von Azure Databricks zu verwenden, müssen Sie zuerst ein persönliches Azure Databricks-Zugriffstoken erstellen. Ausführliche Informationen zu diesem Schritt finden Sie unter Azure Databricks personal access tokens for workspace users.

Um den Databricks-SQL-Treiber für Go mit einer DSN-Verbindungszeichenfolge und dem Codebeispiel unter Herstellen einer Verbindung mit einer DSN-Verbindungszeichenfolge zu authentifizieren, verwenden Sie die folgende DSN-Verbindungszeichenfolgensyntax, für die Folgendes gilt:

  • <personal-access-token> ist das persönliches Zugriffstoken für Azure Databricks aus den Anforderungen.
  • <server-hostname> ist der Serverhostname-Wert aus den Anforderungen.
  • <port-number> ist der Portwert aus den Anforderungen, der in der Regel 443 ist.
  • <http-path> ist der HTTP-Pfad-Wert aus den Anforderungen.

Sie können auch einen oder mehrere der optionalen Parameter anfügen, die weiter oben in diesem Artikel aufgeführt sind.

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

Um den Databricks-SQL-Treiber für Go mit der NewConnector-Funktion zu authentifizieren, verwenden Sie den folgenden Codeschnipsel und das Codebeispiel unter Herstellen einer Verbindung mit der NewConnector-Funktion, bei der davon ausgegangen wird, dass Sie die folgenden Umgebungsvariablen festgelegt haben:

  • DATABRICKS_SERVER_HOSTNAME ist auf den Wert von Serverhostname für Ihren Cluster oder Ihr SQL-Warehouse festgelegt.
  • DATABRICKS_HTTP_PATH ist auf den Wert von HTTP-Pfad für Ihren Cluster oder Ihr SQL-Warehouse festgelegt.
  • DATABRICKS_TOKEN ist auf das persönliche Azure Databricks-Zugriffstoken festgelegt.

Informationen zum Festlegen von Umgebungsvariablen finden Sie in der Dokumentation des Betriebssystems.

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

Microsoft Entra ID-Tokenauthentifizierung

Der Databricks-SQL-Treiber für Go unterstützt Microsoft Entra ID-Token für Azure Databricks-Benutzer*innen oder Microsoft Entra ID-Dienstprinzipale.

Gehen Sie wie folgt vor, um ein Microsoft Entra ID-Zugriffstoken zu erstellen:

  • Für eine*n Azure Databricks-Benutzer*in können Sie die Azure CLI verwenden. Weitere Informationen finden Sie unter Abrufen von Microsoft Entra ID-Token für Benutzer mithilfe der Azure CLI.

    Microsoft Entra ID-Token haben eine Standardlebensdauer von ca. 1 Stunde. Wiederholen Sie diesen Vorgang, um ein neues Microsoft Entra ID-Token zu erstellen.

    Um den Databricks-SQL-Treiber für Go mit einer DSN-Verbindungszeichenfolge und dem Codebeispiel unter Herstellen einer Verbindung mit einer DSN-Verbindungszeichenfolge zu authentifizieren, verwenden Sie die folgende DSN-Verbindungszeichenfolgensyntax, für die Folgendes gilt:

    • <microsoft-entra-id-token> ist Ihr Microsoft Entra ID-Token.
    • <server-hostname> ist der Serverhostname-Wert aus den Anforderungen.
    • <port-number> ist der Portwert aus den Anforderungen, der in der Regel 443 ist.
    • <http-path> ist der HTTP-Pfad-Wert aus den Anforderungen.

    Sie können auch einen oder mehrere der optionalen Parameter anfügen, die weiter oben in diesem Artikel aufgeführt sind.

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

    Um den Databricks-SQL-Treiber für Go mit der NewConnector-Funktion zu authentifizieren, verwenden Sie den folgenden Codeschnipsel und das Codebeispiel unter Herstellen einer Verbindung mit der NewConnector-Funktion, bei der davon ausgegangen wird, dass Sie die folgenden Umgebungsvariablen festgelegt haben:

    • DATABRICKS_SERVER_HOSTNAME ist auf den Wert von Serverhostname für Ihren Cluster oder Ihr SQL-Warehouse festgelegt.
    • DATABRICKS_HTTP_PATH ist auf den Wert von HTTP-Pfad für Ihren Cluster oder Ihr SQL-Warehouse festgelegt.
    • DATABRICKS_TOKEN ist auf Ihr Microsoft Entra ID-Token festgelegt.

    Informationen zum Festlegen von Umgebungsvariablen finden Sie in der Dokumentation des Betriebssystems.

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

OAuth U2M-Authentifizierung (User-to-Machine)

Der Databricks-SQL-Treiber für Go unterstützt ab Version 1.5.0 die OAuth-U2M-Authentifizierung (User-to-Machine, Benutzer-zu-Computer).

Um den Databricks-SQL-Treiber für Go mit einer DSN-Verbindungszeichenfolge und dem Codebeispiel unter Herstellen einer Verbindung mit einer DSN-Verbindungszeichenfolge zu verwenden, wenden Sie die folgende DSN-Verbindungszeichenfolgensyntax an, für die Folgendes gilt:

  • <server-hostname> ist der Serverhostname-Wert aus den Anforderungen.
  • <port-number> ist der Portwert aus den Anforderungen, der in der Regel 443 ist.
  • <http-path> ist der HTTP-Pfad-Wert aus den Anforderungen.

Sie können auch einen oder mehrere der optionalen Parameter anfügen, die weiter oben in diesem Artikel aufgeführt sind.

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

Um den Databricks-SQL-Treiber für Go mit der NewConnector-Funktion zu authentifizieren, müssen Sie Ihrer import-Deklaration zunächst Folgendes hinzufügen:

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

Verwenden Sie dann den folgenden Codeschnipsel und das Codebeispiel unter Herstellen einer Verbindung mit der NewConnector-Funktion, bei der davon ausgegangen wird, dass Sie die folgenden Umgebungsvariablen festgelegt haben:

  • DATABRICKS_SERVER_HOSTNAME ist auf den Wert von Serverhostname für Ihren Cluster oder Ihr SQL-Warehouse festgelegt.
  • DATABRICKS_HTTP_PATH ist auf den Wert von HTTP-Pfad für Ihren Cluster oder Ihr SQL-Warehouse festgelegt.

Informationen zum Festlegen von Umgebungsvariablen finden Sie in der Dokumentation des Betriebssystems.

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

OAuth-Computer-zu-Computer-Authentifizierung (M2M)

Der Databricks-SQL-Treiber für Go unterstützt ab Version 1.5.2 die OAuth-M2M-Authentifizierung (Machine-to-Machine, Computer-zu-Computer).

Um den Databricks-SQL-Treiber für Go mit der OAuth-M2M-Authentifizierung zu verwenden, müssen Sie die folgenden Schritte ausführen:

  1. Erstellen Sie einen Azure Databricks-Dienstprinzipal in Ihrem Azure Databricks-Arbeitsbereich, und erstellen Sie ein OAuth-Geheimnis für diesen Dienstprinzipal.

    Informationen zum Erstellen des Dienstprinzipals und des geheimen OAuth-Schlüssels finden Sie unter Authentifizierung des Zugriffs bei Azure Databricks mit einem Dienstprinzipal unter Verwendung von OAuth (OAuth M2M). Notieren Sie sich den UUID- oder Anwendungs-ID-Wert des Dienstprinzipals und den Geheimniswert für das OAuth-Geheimnis des Dienstprinzipals.

  2. Gewähren Sie diesem Dienstprinzipal Zugriff auf Ihren Cluster oder Ihr Warehouse.

    Informationen dazu, wie Sie dem Dienstprinzipal Zugriff auf Ihren Cluster oder Ihr Warehouse gewähren, finden Sie unter Computeberechtigungen oder Verwaltung eines SQL-Warehouse.

Um den Databricks-SQL-Treiber für Go mit einer DSN-Verbindungszeichenfolge und dem Codebeispiel unter Herstellen einer Verbindung mit einer DSN-Verbindungszeichenfolge zu authentifizieren, verwenden Sie die folgende DSN-Verbindungszeichenfolgensyntax, für die Folgendes gilt:

  • <server-hostname> ist der Serverhostname-Wert aus den Anforderungen.
  • <port-number> ist der Portwert aus den Anforderungen, der in der Regel 443 ist.
  • <http-path> ist der HTTP-Pfad-Wert aus den Anforderungen.
  • <client-id> ist der Wert der UUID oder Anwendungs-ID des Dienstprinzipals.
  • <client-secret> ist der Wert Geheimnis für das OAuth-Geheimnis des Dienstprinzipals.

Sie können auch einen oder mehrere der optionalen Parameter anfügen, die weiter oben in diesem Artikel aufgeführt sind.

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

Um den Databricks-SQL-Treiber für Go mit der NewConnector-Funktion zu authentifizieren, müssen Sie Ihrer import-Deklaration zunächst Folgendes hinzufügen:

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

Verwenden Sie dann den folgenden Codeschnipsel und das Codebeispiel unter Herstellen einer Verbindung mit der NewConnector-Funktion, bei der davon ausgegangen wird, dass Sie die folgenden Umgebungsvariablen festgelegt haben:

  • DATABRICKS_SERVER_HOSTNAME ist auf den Wert von Serverhostname für Ihren Cluster oder Ihr SQL-Warehouse festgelegt.
  • DATABRICKS_HTTP_PATH ist auf den Wert von HTTP-Pfad für Ihren Cluster oder Ihr SQL-Warehouse festgelegt.
  • Legen Sie DATABRICKS_CLIENT_ID auf den UUID- oder Anwendungs-ID-Wert des Dienstprinzipals fest.
  • DATABRICKS_CLIENT_SECRET ist auf den Wert Geheimnis für das OAuth-Geheimnis des Dienstprinzipals festgelegt.

Informationen zum Festlegen von Umgebungsvariablen finden Sie in der Dokumentation des Betriebssystems.

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

Daten abfragen

Im folgenden Codebeispiel wird veranschaulicht, wie Sie den Databricks SQL-Treiber für Go aufrufen können, um eine einfache SQL-Abfrage in einer Azure Databricks-Computeressource auszuführen. Dieser Befehl gibt die ersten beiden Zeilen aus der Tabelle trips im Schema nyctaxi des Katalogs samples zurück.

In diesem Codebeispiel wird die DSN-Verbindungszeichenfolge aus einer Umgebungsvariablen namens DATABRICKS_DSN abgerufen.

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

Verwalten von Dateien in Unity Catalog-Volumes

Mit dem Databricks SQL-Treiber können Sie lokale Dateien in Unity Catalog-Volumes schreiben, Dateien aus Volumes herunterladen und Dateien aus Volumes löschen, wie im folgenden Beispiel gezeigt:

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

Verwenden Sie github.com/databricks/databricks-sql-go/logger, um Nachrichten zu protokollieren, die der Databricks SQL-Treiber für Go ausgibt. Im folgenden Codebeispiel wird sql.Open() benutzt, um ein Datenbankhandle über eine DSN-Verbindungszeichenfolge zu erstellen. In diesem Codebeispiel wird die DSN-Verbindungszeichenfolge aus einer Umgebungsvariablen namens DATABRICKS_DSN abgerufen. Alle Protokollmeldungen, die auf der debug Ebene und darunter ausgegeben werden, werden in die results.log Datei geschrieben.

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

Testen

Um Ihren Code zu testen, verwenden Sie Go-Testframeworks wie die Standardbibliothek testing. Um Ihren Code unter simulierten Bedingungen zu testen, ohne Azure Databricks-REST-API-Endpunkte aufzurufen oder den Status Ihrer Azure Databricks-Konten oder -Arbeitsbereiche zu ändern, können Sie Go-Simulationsbibliotheken wie testify verwenden.

Beispielsweise enthält die folgende Datei mit dem Namen helpers.go eine GetDBWithDSNPAT-Funktion, die eine Azure Databricks-Arbeitsbereichsverbindung zurückgibt, eine GetNYCTaxiTrips-Funktion, die Daten aus der trips-Tabelle im nyctaxi-Schema des Katalogs samples zurückgibt, und eine PrintNYCTaxiTrips-Funktion, die die zurückgegebenen Daten druckt:

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

Und die folgende Datei mit dem Namen main.go ruft diese Funktionen auf:

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

Die folgende Datei mit dem Namen helpers_test.go testet, ob die GetNYCTaxiTrips Funktion die erwartete Antwort zurückgibt. Anstatt eine echte Verbindung mit dem Zielarbeitsbereich zu erstellen, simuliert dieser Test ein sql.DB-Objekt. Zudem simuliert der Test einige Daten, die dem Schema und den Werten aus den realen Daten entsprechen. Der Test gibt die simulierten Daten über die simulierte Verbindung zurück und überprüft dann, ob einer der simulierten Datenzeilenwerte dem erwarteten Wert entspricht.

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

Da die Funktion GetNYCTaxiTrips eine SELECT-Anweisung enthält und daher den Status der Tabelle trips nicht ändert, sind in diesem Beispiel nicht unbedingt Pseudoelemente (Mocking) erforderlich. Mithilfe von Pseudoelementen können Sie Ihre Tests jedoch schnell ausführen, ohne darauf zu warten, dass eine tatsächliche Verbindung mit dem Arbeitsbereich hergestellt wird. Außerdem können Sie simulierte Tests mehrmals für Funktionen ausführen, die den Status einer Tabelle ändern können, z. B. INSERT INTO, UPDATE und DELETE FROM.

Zusätzliche Ressourcen