メインコンテンツまでスキップ

Go 用 Databricks SQL ドライバー

Databricks SQLDriver for Go は、Go SQLコードを使用してDatabricks コンピュート リソースで コマンドを実行できるようにする Go ライブラリです。この記事では、Databricks SQL Driver for Go の README、API リファレンス、および例を補足します。

必要条件​

Databricks SQL Driver for Go の概要​

  1. Go 1.20 以降が既にインストールされ、既存の Go コード プロジェクトが既に作成されている開発マシンで、次のように go mod init コマンドを実行して Go コードの依存関係を追跡するための go.mod ファイルを作成します。

    Bash
    go mod init sample
  2. go mod edit -require コマンドを実行し、リリースに記載されている最新バージョンの Databricks SQL Driver for Go パッケージv1.5.2に置き換えて、Databricks SQL Driver for Go パッケージに依存関係を取ります。

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

    go.modファイルは次のようになります。

    Go
    module sample

    go 1.20

    require github.com/databricks/databricks-sql-go v1.5.2
  3. プロジェクトで、Go 用の Databricks SQL ドライバーをインポートする Go コード ファイルを作成します。 次の例では、次の内容の main.go という名前のファイルで、 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. 不足しているモジュールの依存関係を追加するには、 go mod tidy コマンドを実行します。

    Bash
    go mod tidy
注記

エラーが表示された場合 go: warning: "all" matched no packagesは、Go 用の Databricks SQL ドライバーをインポートする Go コード ファイルを追加するのを忘れていました。

  1. mainモジュール内のパッケージのビルドとテストをサポートするために必要なすべてのパッケージのコピーを作成するには、次のコマンドを実行してgo mod vendor。

    Bash
    go mod vendor
  2. 必要に応じてコードを変更し、Databricks 認証の DATABRICKS_DSN 環境変数を設定します。「DSN 接続文字列を使用した接続」も参照してください。

  3. main.goという名前のファイルを想定して、go run コマンドを実行して、Go コード ファイルを実行します。

    Bash
    go run main.go
  4. エラーが返されない場合は、 ワークスペースで Databricks SQLDriver for GoDatabricksDatabricksSQL が正常に認証され、そのワークスペース内の実行中の クラスターまたは ウェアハウスに接続されています。

DSN 接続文字列を使用して接続する​

クラスターと SQLウェアハウスにアクセスするには、sql.Open() を使用して、データソース名 (DSN) 接続文字列を介してデータベースハンドルを作成します。 次のコード例では、 DATABRICKS_DSNという名前の環境変数から 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)
}
}

DSN 接続文字列を正しい形式で指定するには、「 認証」の DSN 接続文字列の例を参照してください。 たとえば、Databricks 個人用アクセス トークン認証の場合は、次の構文を使用します。

  • <personal-access-token> 要件からのあなたのDatabricks個人用アクセストークンです。
  • <server-hostname> は、 要件に含まれるサーバーのホスト名の値です 。
  • <port-number> は要件の ポート 値で、通常は 443です。
  • <http-path> は、 要件からの HTTP パスの値です 。
  • <paramX=valueX> は、この記事の後半に示す 1 つ以上の 省略可能なパラメーター です。
token:<personal-access-token>@<server-hostname>:<port-number>/<http-path>?<param1=value1>&

たとえば、クラスターの場合は次のようになります。

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

たとえば、 SQLウェアハウスの場合、次のようになります。

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

セキュリティのベストプラクティスとして、このDSN接続文字列をGoコードにハードコードしないでください。 代わりに、この DSN 接続文字列を安全な場所から取得する必要があります。 たとえば、この記事で前述したコード例では、環境変数を使用しました。

省略可能なパラメーター​

  • サポートされているオプションの接続パラメーターは、 <param=value>で指定できます。 より頻繁に使用されるものには、次のものがあります。

    • catalog: セッションの初期カタログ名を設定します。
    • schema: セッションの初期スキーマ名を設定します。
    • maxRows: リクエストごとに取得される最大行数を設定します。 デフォルトは 10000です。
    • timeout: サーバークエリ実行のタイムアウト (秒単位) を追加します。 デフォルトはタイムアウトなしです。
    • userAgentEntry: パートナーを識別するために使用されます。詳細については、パートナーのドキュメントを参照してください。
  • サポートされているオプションのセッション パラメーターは、 param=valueで指定できます。 より頻繁に使用されるものには、次のものがあります。

    • ansi_mode: Boolean 文字列。 セッション・ステートメントが ANSI SQL 仕様で指定されたルールに従うためのtrue。システムのデフォルトは false です。
    • timezone: 文字列 (例: America/Los_Angeles. セッションのタイムゾーンを設定します。 システムのデフォルトは UTC です。
    • query_tags: カンマ区切りのキーの文字列 system.query.historyで追跡するために SQL クエリに添付するペア (例: team:engineering,dashboard:abc123 )。

たとえば、 SQLウェアハウスの場合、次のようになります。

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

NewConnector機能で接続する​

または、sql.OpenDB() を使用して、dbsql.NewConnector() で作成された新しいコネクタ オブジェクトを介してデータベース ハンドルを作成します (新しいコネクタ オブジェクトを使用して Databricks クラスターおよび SQLウェアハウスに接続するには、v1.0.0 以降の Databricks SQL Driver for Go が必要です)。 例えば:

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

NewConnector 設定の正しいセットを指定するには、認証の例を参照してください。

注記

セキュリティのベストプラクティスとして、 NewConnector 設定をGoコードにハードコードしないでください。 代わりに、安全な場所からこれらの値を取得する必要があります。 たとえば、上記のコードでは環境変数が使用されています。

よく使われる機能オプションには、次のものがあります。

  • WithAccessToken(<access-token>): 要件からの 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」、および「query_tags」を含むセッションパラメーターがあります。 オプションmap[string]string 。
  • WithTimeout(<timeout>).サーバークエリ実行のタイムアウト ( time.Duration単位)。 デフォルトはタイムアウトなしです。 随意。
  • WithUserAgentEntry(<isv-name-plus-product-name>).パートナーを識別するために使用されます。詳細については、パートナーのドキュメントを参照してください。 オプションの string。

例えば:

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

認証​

Go 用 Databricks SQL ドライバーでは、次の Databricks 認証の種類がサポートされています。

Databricks 個人用アクセス トークン認証​

Databricks個人アクセス権認証でDatabricks SQL Driver for Go を使用するには、まずDatabricks個人アクセス権を作成する必要があります。 このステップの詳細については、 「ワークスペース ユーザー向けの個人アクセストークンの作成」を参照してください。

DSN 接続文字列と「 DSN 接続文字列を使用した接続」のコード例を使用して Databricks SQL Driver for Go を認証するには、次の DSN 接続文字列構文を使用します。

  • <personal-access-token> 要件からのあなたのDatabricks個人用アクセストークンです。
  • <server-hostname> は、 要件に含まれるサーバーのホスト名の値です 。
  • <port-number> は要件の ポート 値で、通常は 443です。
  • <http-path> は、 要件からの HTTP パスの値です 。

また、この記事で前述した 1 つ以上の Optional パラメーター を追加することもできます。

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

NewConnector 関数を使用して Go 用 Databricks SQL ドライバーを認証するには、次のコード スニペットと「NewConnector 関数との接続」のコード例を使用します。これは、次の環境変数が設定されていることを前提としています。

  • DATABRICKS_SERVER_HOSTNAMEクラスターまたはウェアハウスの Server Hostname 値 SQLに設定します。
  • DATABRICKS_HTTP_PATHで、クラスターまたはSQL ウェアハウスの HTTP パス 値に設定します。
  • DATABRICKS_TOKENで、Databricks 個人用アクセス トークンに設定されます。

環境変数を設定するには、オペレーティングシステムのドキュメントを参照してください。

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

OAuth ユーザーマシン間 (U2M) 認証​

Databricks SQL Driver for Go バージョン 1.5.0 以降では、 OAuth ユーザーマシン間 (U2M) 認証がサポートされています。

DSN 接続文字列と「 DSN 接続文字列を使用した接続」のコード例で Go 用 Databricks SQL ドライバーを使用するには、次の DSN 接続文字列構文を使用します。

  • <server-hostname> は、 要件に含まれるサーバーのホスト名の値です 。
  • <port-number> は要件の ポート 値で、通常は 443です。
  • <http-path> は、 要件からの HTTP パスの値です 。

また、この記事で前述した 1 つ以上の Optional パラメーター を追加することもできます。

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

NewConnector 関数を使用して Databricks SQL Driver for Go を認証するには、まず import 宣言に次のものを追加する必要があります。

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

次に、次のコード スニペットと「NewConnector 関数を使用した接続」のコード例を使用します。これは、次の環境変数を設定していることを前提としています。

  • DATABRICKS_SERVER_HOSTNAMEクラスターまたはウェアハウスの Server Hostname 値 SQLに設定します。
  • DATABRICKS_HTTP_PATHで、クラスターまたはSQL ウェアハウスの HTTP パス 値に設定します。

環境変数を設定するには、オペレーティングシステムのドキュメントを参照してください。

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

OAuth マシン間 (M2M) 認証​

Databricks SQL Driver for Go バージョン 1.5.2 以降では、 OAuth マシン間 (M2M) 認証がサポートされています。

OAuth M2M 認証で Go 用 Databricks SQL ドライバーを使用するには、次の操作を行う必要があります。

  1. DatabricksワークスペースにDatabricks サービスプリンシパルを作成し、そのサービスプリンシパルのOAuthシークレットを作成します。

    サービスプリンシパルとそのOAuthシークレットを作成するには、「サービスプリンシパルのアクセスをOAuthでDatabricksに許可する」を参照してください。サービスプリンシパルの UUID または アプリケーション ID の値と、サービスプリンシパルのOAuthシークレットの Secret 値をメモします。

  2. そのサービスプリンシパルに、クラスターまたはウェアハウスへのアクセス権を付与します。

    サービスプリンシパルにクラスターまたはウェアハウスへのアクセス権を付与するには、「コンピュートのアクセス許可」または「SQLウェアハウスの管理」を参照してください。

DSN 接続文字列と「 DSN 接続文字列を使用した接続」のコード例を使用して Databricks SQL Driver for Go を認証するには、次の DSN 接続文字列構文を使用します。

  • <server-hostname> は、 要件に含まれるサーバーのホスト名の値です 。
  • <port-number> は要件の ポート 値で、通常は 443です。
  • <http-path> は、 要件からの HTTP パスの値です 。
  • <client-id> は、サービスプリンシパルの UUID または アプリケーション ID の値です。
  • <client-secret> は、サービスプリンシパルの シークレットの Secret OAuth 値です。

また、この記事で前述した 1 つ以上の Optional パラメーター を追加することもできます。

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

NewConnector 関数を使用して Databricks SQL Driver for Go を認証するには、まず import 宣言に次のものを追加する必要があります。

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

次に、次のコード スニペットと「NewConnector 関数を使用した接続」のコード例を使用します。これは、次の環境変数を設定していることを前提としています。

  • DATABRICKS_SERVER_HOSTNAMEクラスターまたはウェアハウスの Server Hostname 値 SQLに設定します。
  • DATABRICKS_HTTP_PATHで、クラスターまたはSQL ウェアハウスの HTTP パス 値に設定します。
  • DATABRICKS_CLIENT_IDで、サービスプリンシパルの UUID または アプリケーション ID の値に設定します。
  • DATABRICKS_CLIENT_SECRETで、サービスプリンシパルの OAuth シークレットの Secret 値に設定します。

環境変数を設定するには、オペレーティングシステムのドキュメントを参照してください。

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

データのクエリ​

次のコード例は、Databricks SQL Driver for GoSQL Databricksを呼び出して、 コンピュート リソースに対する基本的な Microsoft クエリを実行する方法を示しています。このコマンドは、samples カタログの nyctaxi スキーマの trips テーブルから最初の 2 つのローを返します。

このコード例では、DATABRICKS_DSNという名前の環境変数から 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)
}
}

Unity Catalog ボリューム内のファイルを管理する​

Databricks SQL ドライバーを使用すると、次の例に示すように、Unity Catalog ボリュームへのローカル ファイルの書き込み、ボリュームからのファイルのダウンロード、ボリュームからのファイルの削除を行うことができます。

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

伐採​

github.com/databricks/databricks-sql-go/logger を使用して、Databricks SQL Driver for Go が出力するメッセージをログに記録します。次のコード例では、 sql.Open() を使用して、DSN 接続文字列を介してデータベース ハンドルを作成します。 このコード例では、 DATABRICKS_DSNという名前の環境変数から DSN 接続文字列を取得します。 debug レベル以下で出力されるすべてのログ メッセージは、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)
}
}

ステートメント実行 API の使用​

Databricks SQL Driver for Go は、default の Thrift プロトコルの代わりに、REST ベースの実行パスであるステートメント実行 API を使用して接続できます。Lakehouse Real-Time コンピュートに接続するには、このパスを使用する必要があります。

カーネルバックエンドはビルドタグの下でコンパイルされ、事前構築された組み込みバイナリをLinkします。ドライバー v1.15.0 以降、Go 1.25 以降、および Linux (amd64/arm64/arm)、Darwin (amd64/arm64)、Windows (amd64/arm64) などのサポートされているプラットフォーム上の C ツールチェーン (CGO) が必要です。Windows では、MSYS2 や mingw-w64 などの MinGW/GNU ツールチェーンを使用します。

Shell
go get github.com/databricks/databricks-sql-go@v1.15.0

databricks_kernel タグと CGO_ENABLED=1 を使用して構築:

Shell
CGO_ENABLED=1 go build -tags databricks_kernel ./...

接続時に、WithUseKernel(true)を渡すか(またはDSNでuseKernel=trueを設定する)、次の操作を行います。

Go
connector, err := dbsql.NewConnector(
dbsql.WithServerHostname(host),
dbsql.WithHTTPPath(httpPath),
dbsql.WithAccessToken(token),
dbsql.WithUseKernel(true),
)
if err != nil {
panic(err)
}

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

この実行パスは、WithUseKernel(true)を設定した場合にのみ使用されます。それ以外の場合、ドライバーは以前のバージョンと同様に動作します。databricks_kernelビルドタグがない場合、WithUseKernel(true)は接続時に明確な「kernel not compiled」エラーを返し、Thriftにサイレントフォールバックすることはありません。一部の操作はこのパスではまだサポートされておらず、「not supported」エラーが発生します。

テスティング​

コードをテストするには、 テスト 標準ライブラリなどの Go テストフレームワークを使用します。 Databricks REST API エンドポイントを呼び出したり、Databricks アカウントやワークスペースの状態を変更したりせずに、シミュレートされた条件下でコードをテストするには、 testfify などの Go モック ライブラリを使用します。

たとえば、Databricks ワークスペース接続を返す GetDBWithDSNPAT 関数、samples カタログの nyctaxi スキーマの trips テーブルからデータを返す GetNYCTaxiTrips 関数、および返されたデータを出力するPrintNYCTaxiTripsを含む 、helpers.go という名前の次のファイルがあるとします。

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

そして、これらの関数を呼び出す main.go という名前の次のファイルがあるとします。

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 オブジェクトをモックします。また、このテストでは、実際のデータにあるスキーマと値に準拠する一部のデータをモックします。このテストでは、モックされた接続を介してモックされたデータが返され、モックされたデータ行の値の 1 つが期待値と一致するかどうかがチェックされます。

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

GetNYCTaxiTrips 関数には SELECT ステートメントが含まれているため、trips テーブルの状態は変更されないため、この例ではモックは絶対に必要ではありません。ただし、モックを使用すると、ワークスペースとの実際の接続を待たずに、テストをすばやく実行できます。また、モックを使用すると、テーブルの状態を変更する可能性のある関数 ( 、 、 INSERT INTO、 UPDATE、 DELETE FROMなど) のシミュレートされたテストを複数回実行できます。

追加のリソース​