共用方式為


Databricks SQL Driver for Go

Databricks SQL Driver for Go 是一個 Go 連結庫,可讓您使用 Go 程式代碼在 Azure Databricks 計算資源上執行 SQL 命令。 本文補充 Databricks SQL Driver for Go 自述檔API 參考範例

需求

  • 執行 Go 版本 1.20 或更新版本的開發電腦。 若要列印已安裝的 Go 版本,請執行 命令 go version下載並安裝 Go
  • 現有的 叢集SQL 倉儲
  • 現有叢集或 SQL 倉儲的伺服器主機名HTTP 路徑值。

開始使用 Databricks SQL Driver for Go

  1. 在已安裝 Go 1.20 或更新版本的開發電腦上,以及已建立現有的 Go 程式代碼專案,執行 go mod init 命令來建立go.mod檔案來追蹤您的 Go 程式代碼相依性,例如:

    go mod init sample
    
  2. 執行 go mod edit -require 命令以相依於 Databricks SQL Driver for Go 套件,並將 取代v1.5.2為最新版的 Databricks SQL Driver for Go 套件,如版本所列

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

    您的 go.mod 檔案現在看起來應該像這樣:

    module sample
    
    go 1.20
    
    require github.com/databricks/databricks-sql-go v1.5.2
    
  3. 在您的專案中,建立可匯入 Databricks SQL Driver for Go 的 Go 程式代碼檔案。 下列範例會在名為 main.go 且具有下列內容的檔案中,列出 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. 執行 命令以新增任何遺漏的 go mod tidy 模組相依性:

    go mod tidy
    

    注意

    如果您收到錯誤 go: warning: "all" matched no packages,您忘記新增匯入 Databricks SQL Driver for Go 的 Go 程式代碼檔案。

  5. 執行 go mod vendor 命令,在模組中main建立支援套件組建和測試所需的所有套件複本:

    go mod vendor
    
  6. 視需要修改您的程式代碼,DATABRICKS_DSN以設定 Azure Databricks 驗證環境變數。 另請參閱使用 DSN 連接字串 進行連線。

  7. 執行 命令,以執行名為 main.gogo run 的檔案執行 Go 程式代碼檔案:

    go run main.go
    
  8. 如果未傳回任何錯誤,您已成功使用 Azure Databricks 工作區驗證 Databricks SQL Driver for Go,並連線到該工作區中執行中的 Azure Databricks 叢集或 SQL 倉儲。

使用 DSN 連接字串 連線

若要存取叢集和 SQL 倉儲,請使用 sql.Open() 透過資料來源名稱 (DSN) 連接字串 建立資料庫句柄。 此程式代碼範例會從名為 DATABRICKS_DSN的環境變數擷取 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)
  }
}

若要以正確的格式指定 DSN 連接字串,請參閱驗證中的 DSN 連接字串 範例。 例如,針對 Azure Databricks 個人存取令牌驗證,請使用下列語法,其中:

  • <personal-access-token> 是來自需求的 Azure Databricks 個人存取令牌。
  • <server-hostname>是來自需求的伺服器主機名值。
  • <port-number>是來自需求的埠值,通常是 443
  • <http-path>是來自需求的 HTTP 路徑值。
  • <paramX=valueX> 是本文稍後所列的一或多個 選擇性參數
token:<personal-access-token>@<server-hostname>:<port-number>/<http-path>?<param1=value1>&<param2=value2>

例如,針對叢集:

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

例如,針對 SQL 倉儲:

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

注意

作為安全性最佳做法,您不應該將此 DSN 硬式編碼 連接字串 到您的 Go 程式代碼中。 相反地,您應該從安全的位置擷取此 DSN 連接字串。 例如,本文稍早的程式代碼範例使用環境變數。

選擇性參數

  • 支援的選擇性連接參數可以在 中 <param=value>指定。 一些較常用專案包括:
    • catalog:在工作階段中設定初始目錄名稱。
    • schema:在工作階段中設定初始架構名稱。
    • maxRows:設定每個要求擷取的數據列數目上限。 預設值為 10000
    • timeout:新增伺服器查詢執行的逾時(以秒為單位)。 預設值為無逾時。
    • userAgentEntry:用來識別合作夥伴。 如需詳細資訊,請參閱合作夥伴的檔。
  • 支援的選擇性會話參數可以在 中 param=value指定。 一些較常用專案包括:
    • ansi_mode:布爾字串。 true 表示符合 ANSI SQL 規格所指定規則的會話語句。 系統預設值為 false。
    • timezone:字串,例如 America/Los_Angeles。 設定工作階段的時區。 系統預設值為UTC。

例如,針對 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

使用函式連線NewConnector

或者,使用 sql.OpenDB() 透過使用 建立的新連接器物件來建立 dbsql.NewConnector() 資料庫句柄(使用新的連接器對象連線到 Azure Databricks 叢集和 SQL 倉儲需要 Databricks SQL Driver for Go 的 v1.0.0 或更高版本)。 例如:

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

若要指定正確的設定集NewConnector,請參閱驗證中的範例。

注意

作為安全性最佳做法,您不應該將設定 NewConnector 硬式編碼到 Go 程式代碼中。 相反地,您應該從安全的位置擷取這些值。 例如,上述程式代碼會使用環境變數。

一些較常用的功能選項包括:

  • WithAccessToken(<access-token>):來自需求的 Azure Databricks 個人存取令牌。 必要 string
  • WithServerHostname(<server-hostname>):來自需求的伺服器主機名值。 必要 string
  • WithPort(<port>):伺服器的埠號碼,通常是 443。 必要 int
  • WithHTTPPath(<http-path>):來自需求的 HTTP 路徑值。 必要 string
  • WithInitialNamespace(<catalog>, <schema>):工作階段中的目錄和架構名稱。 選擇性 string, string
  • WithMaxRows(<max-rows>):每個要求擷取的數據列數目上限。 預設值為 10000. 選擇性 int
  • WithSessionParams(<params-map>):會話參數,包括 “timezone” 和 “ansi_mode”。 選擇性 map[string]string
  • WithTimeout(<timeout>). 伺服器查詢執行的逾時 (in time.Duration) 。 預設值為無逾時。 選擇性。
  • WithUserAgentEntry(<isv-name-plus-product-name>). 用來識別合作夥伴。 如需詳細資訊,請參閱合作夥伴的檔。 選擇性 string

例如:

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

驗證

Databricks SQL Driver for Go 支援下列 Azure Databricks 驗證類型:

Databricks SQL Driver for Go 尚不支援下列 Azure Databricks 驗證類型:

Databricks 個人存取令牌驗證

若要搭配 Azure Databricks 個人存取令牌驗證使用 Databricks SQL Driver for Go,您必須先建立 Azure Databricks 個人存取令牌,如下所示:

  1. 在 Azure Databricks 工作區中,按兩下頂端列中的 Azure Databricks 使用者名稱,然後從下拉式清單中選取 [設定 ]。
  2. 按兩下 [ 開發人員]。
  3. 按兩下 [存取令牌] 旁的 [管理]。
  4. 按一下 [產生新權杖]
  5. (選擇性)輸入批注,協助您在未來識別此令牌,並變更令牌的預設存留期 90 天。 若要建立沒有存留期的令牌(不建議),請將 [ 存留期(天)] 方塊保留空白(空白)。
  6. 按一下 [產生]
  7. 將顯示的令牌複製到安全的位置,然後按兩下 [ 完成]。

注意

請務必將複製的令牌儲存在安全的位置。 請勿與其他人共享複製的令牌。 如果您遺失複製的令牌,就無法重新產生完全相同的令牌。 相反地,您必須重複此程式來建立新的令牌。 如果您遺失複製的令牌,或您認為令牌已遭入侵,Databricks 強烈建議您按兩下存取令牌頁面上令牌旁邊的垃圾桶 (Revoke) 圖示,立即從工作區中刪除該令牌

如果您無法在工作區中建立或使用令牌,這可能是因為您的工作區系統管理員已停用令牌,或未授與您建立或使用令牌的許可權。 請參閱您的工作區管理員或下列專案:

若要使用 DSN 連接字串 驗證 Databricks SQL Driver for Go,以及使用 DSN 連接字串 連線中的程式碼範例,請使用下列 DSN 連接字串 語法,其中:

  • <personal-access-token> 是來自需求的 Azure Databricks 個人存取令牌。
  • <server-hostname>是來自需求的伺服器主機名值。
  • <port-number>是來自需求的埠值,通常是 443
  • <http-path>是來自需求的 HTTP 路徑值。

您也可以附加本文先前所列的一或多個 選擇性參數

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

若要使用 NewConnector 函式驗證 Databricks SQL Driver for Go,請使用下列代碼段和 NewConnector 函式中的程式代碼範例,假設您已設定下列環境變數:

  • DATABRICKS_SERVER_HOSTNAME設定為叢集或 SQL 倉儲的伺服器 主機名 值。
  • DATABRICKS_HTTP_PATH,設定為 叢集或 SQL 倉儲的 HTTP 路徑 值。
  • DATABRICKS_TOKEN,設定為 Azure Databricks 個人存取令牌。

若要設定環境變數,請參閱作業系統的檔。

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 (先前稱為 Azure Active Directory) 令牌驗證

Databricks SQL Driver for Go 支援 Azure Databricks 使用者或 Microsoft Entra ID 服務主體Microsoft Entra ID(先前稱為 Azure Active Directory) 令牌。

若要建立Microsoft Entra ID 存取令牌,請執行下列動作:

  • 針對 Azure Databricks 使用者,您可以使用 Azure CLI。 請參閱 使用 Azure CLI 取得使用者Microsoft Entra ID (先前稱為 Azure Active Directory) 令牌。

    • 如需Microsoft Entra ID 服務主體,請參閱 使用 Azure CLI 取得Microsoft Entra ID 存取令牌。 若要建立Microsoft Entra ID 受控服務主體,請參閱 管理服務主體

    Microsoft Entra 識別碼令牌的預設存留期約為 1 小時。 若要建立新的Microsoft Entra ID 令牌,請重複此程式。

    若要使用 DSN 連接字串 驗證 Databricks SQL Driver for Go,以及使用 DSN 連接字串 連線中的程式碼範例,請使用下列 DSN 連接字串 語法,其中:

    • <microsoft-entra-id-token> 是您的Microsoft Entra ID 令牌。
    • <server-hostname>是來自需求的伺服器主機名值。
    • <port-number>是來自需求的埠值,通常是 443
    • <http-path>是來自需求的 HTTP 路徑值。

    您也可以附加本文先前所列的一或多個 選擇性參數

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

    若要使用 NewConnector 函式驗證 Databricks SQL Driver for Go,請使用下列代碼段和 NewConnector 函式中的程式代碼範例,假設您已設定下列環境變數:

    • DATABRICKS_SERVER_HOSTNAME設定為叢集或 SQL 倉儲的伺服器 主機名 值。
    • DATABRICKS_HTTP_PATH,設定為 叢集或 SQL 倉儲的 HTTP 路徑 值。
    • DATABRICKS_TOKEN,設定為 Microsoft Entra ID 令牌。

    若要設定環境變數,請參閱作業系統的檔。

    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) 驗證

Databricks SQL Driver for Go 1.5.0 版和更新版本支援 OAuth 使用者對計算機 (U2M) 驗證

若要搭配 DSN 連接字串 使用 Databricks SQL Driver for Go,以及使用 DSN 連接字串 連線中的程式碼範例,請使用下列 DSN 連接字串 語法,其中:

  • <server-hostname>是來自需求的伺服器主機名值。
  • <port-number>是來自需求的埠值,通常是 443
  • <http-path>是來自需求的 HTTP 路徑值。

您也可以附加本文先前所列的一或多個 選擇性參數

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

若要使用 NewConnector 函式驗證 Databricks SQL Driver for Go,您必須先將下列內容新增至宣告 import

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

然後使用下列代碼段和 Connect 與 NewConnector 函式中的程式代碼範例,假設您已設定下列環境變數:

  • DATABRICKS_SERVER_HOSTNAME設定為叢集或 SQL 倉儲的伺服器 主機名 值。
  • DATABRICKS_HTTP_PATH,設定為 叢集或 SQL 倉儲的 HTTP 路徑 值。

若要設定環境變數,請參閱作業系統的檔。

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 計算機對電腦 (M2M) 驗證

Databricks SQL Driver for Go 1.5.2 版和更新版本支援 OAuth 計算機對計算機 (M2M) 驗證

若要搭配 OAuth M2M 驗證使用 Databricks SQL Driver for Go,您必須執行下列動作:

  1. 在 Azure Databricks 工作區中建立 Azure Databricks 服務主體,併為該服務主體建立 OAuth 秘密。

    若要建立服務主體及其 OAuth 秘密,請參閱 使用服務主體向 Azure Databricks 進行驗證。 記下服務主體的 UUID應用程式識別碼值,以及服務主體 OAuth 秘密的秘密值。

  2. 為該服務主體提供叢集或倉儲的存取權。

    若要授與服務主體對叢集或倉儲的存取權,請參閱 計算許可權管理 SQL 倉儲

若要使用 DSN 連接字串 驗證 Databricks SQL Driver for Go,以及使用 DSN 連接字串 連線中的程式碼範例,請使用下列 DSN 連接字串 語法,其中:

  • <server-hostname>是來自需求的伺服器主機名值。
  • <port-number>是來自需求的埠值,通常是 443
  • <http-path>是來自需求的 HTTP 路徑值。
  • <client-id> 是服務主體的 UUID應用程式識別碼 值。
  • <client-secret>是服務主體 OAuth 秘密的秘密值。

您也可以附加本文先前所列的一或多個 選擇性參數

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

若要使用 NewConnector 函式驗證 Databricks SQL Driver for Go,您必須先將下列內容新增至宣告 import

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

然後使用下列代碼段和 Connect 與 NewConnector 函式中的程式代碼範例,假設您已設定下列環境變數:

  • DATABRICKS_SERVER_HOSTNAME設定為叢集或 SQL 倉儲的伺服器 主機名 值。
  • DATABRICKS_HTTP_PATH,設定為 叢集或 SQL 倉儲的 HTTP 路徑 值。
  • DATABRICKS_CLIENT_ID,設定為服務主體的 UUID應用程式識別碼 值。
  • DATABRICKS_CLIENT_SECRET,設定為 服務主體的 OAuth 秘密的 Secret 值。

若要設定環境變數,請參閱作業系統的檔。

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

查詢資料

下列程式代碼範例示範如何呼叫 Databricks SQL Driver for Go,以在 Azure Databricks 計算資源上執行基本 SQL 查詢。 此命令會從trips目錄nyctaxi架構中的samples數據表傳回前兩個數據列。

此程式代碼範例會從名為DATABRICKS_DSN環境變數擷取 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)
  }
}

管理 Unity 目錄磁碟區中的檔案

Databricks SQL Driver 可讓您將本機檔案寫入 Unity 目錄 磁碟區、從磁碟區下載檔,以及從磁碟區中刪除檔案,如下列範例所示:

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

記錄

使用 github.com/databricks/databricks-sql-go/logger 來記錄 Databricks SQL Driver for Go 發出的訊息。 下列程式代碼範例會使用 sql.Open() 透過 DSN 連接字串 建立資料庫句柄。 此程式代碼範例會從名為DATABRICKS_DSN的環境變數擷取 DSN 連接字串。 在層級和下方發出 debug 的所有記錄訊息都會寫入檔案 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)
  }
}

測試

若要測試程序代碼,請使用 Go 測試架構,例如 測試 標準連結庫。 若要在模擬條件下測試程序代碼,而不呼叫 Azure Databricks REST API 端點,或變更 Azure Databricks 帳戶或工作區的狀態,請使用 Go 模擬連結庫,例如 testfify

例如,假設下列名為 helpers.go 的檔案,其中包含傳GetDBWithDSNPAT回 Azure Databricks 工作區連線的nyctaxi函式、GetNYCTaxiTripstrips目錄架構中samples數據表傳回數據的函式,以及PrintNYCTaxiTrips列印傳回數據的 :

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

並指定下列名為 的檔案,其會 main.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)
}

下列名為 helpers_test.go 的檔案會測試函 GetNYCTaxiTrips 式是否傳回預期的回應。 此測試會模擬 sql.DB 物件,而不是建立與目標工作區的實際連線。 測試也會模擬一些符合實際數據的架構和值的數據。 測試會透過模擬連接傳回仿真的數據,然後檢查其中一個仿真的數據列值是否符合預期的值。

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

因為函 GetNYCTaxiTrips 式包含 SELECT 語句,因此不會變更數據表的狀態 trips ,所以在此範例中不需要模擬。 不過,模擬可讓您快速執行測試,而不需要等待實際連線與工作區建立。 此外,模擬可讓您針對可能會變更資料表狀態的函式執行模擬測試多次,例如 INSERT INTOUPDATEDELETE FROM

其他資源

  • GitHub 上的 Databricks SQL Driver for Go 存放
  • 資料庫 /sql 套件 首頁
  • GitHub 上的 Databricks SQL Driver for Go 範例