| name | databricks-isv-go-sql-driver |
| description | PWAF-compliant Databricks SQL Driver for Go (databricks-sql-go): PAT, OAuth M2M, OAuth U2M (browser + token-env + custom OAuth app PKCE), WithUserAgentEntry. Use when building or testing integrations that run SQL queries via a Databricks SQL warehouse. |
Databricks SQL Driver for Go (ISV)
Use this skill when implementing or testing Databricks SQL Driver for Go (databricks-sql-go) integrations for PWAF-compliant SQL query execution via a Databricks SQL warehouse.
PWAF Documentation Links
Requirements
- Driver:
github.com/databricks/databricks-sql-go v1.5.2+
- Go: 1.20+
- SQL Warehouse: Required (
DATABRICKS_HTTP_PATH)
- Install:
go get github.com/databricks/databricks-sql-go@latest
Authentication Comparison
| Method | PWAF Status | Auto Token Refresh | Browser Required | Use Case |
|---|
| PAT | ⚠️ Limited | No | No | Testing only |
| OAuth M2M | ✅ Recommended | Yes (driver-native) | No | Production/automated |
| U2M Custom OAuth | ✅ Recommended (ISV) | No | Yes | Interactive (custom app) |
| U2M Token-Env | ✅ Supported | No | No | Headless/CI |
ISV Note: For user-interactive flows, use U2M Custom OAuth with your registered OAuth app (Account Console → App connections). This provides custom branding, audit trails, and scoped permissions. The driver's built-in U2M browser auth uses a generic databricks-sql-connector app which is not appropriate for ISV applications.
Host Normalization Helper
The driver's WithServerHostname expects a bare hostname (no https://):
import "strings"
func serverHostname(host string) string {
s := strings.TrimPrefix(host, "https://")
s = strings.TrimPrefix(s, "http://")
if idx := strings.Index(s, "/"); idx >= 0 {
s = s[:idx]
}
return s
}
Environment Variables Reference
| Variable | Required For | Description |
|---|
DATABRICKS_HOST | All | Workspace URL (e.g., https://myworkspace.cloud.databricks.com) |
DATABRICKS_HTTP_PATH | All | SQL warehouse HTTP path (e.g., /sql/1.0/warehouses/abc123) |
DATABRICKS_TOKEN | PAT | Personal access token |
DATABRICKS_CLIENT_ID | OAuth M2M | Service principal UUID |
DATABRICKS_CLIENT_SECRET | OAuth M2M | Service principal OAuth secret |
DATABRICKS_U2M_CLIENT_ID | U2M Custom OAuth | Custom OAuth app client ID from App connections |
DATABRICKS_U2M_CLIENT_SECRET | U2M Custom OAuth (optional) | Custom OAuth app client secret |
DATABRICKS_REDIRECT_URI | U2M Custom OAuth (optional) | Custom redirect URI (default: http://localhost:8040/callback) |
DATABRICKS_ACCESS_TOKEN | U2M Token-Env | Pre-obtained OAuth access token |
DATABRICKS_AUTH_TYPE | Multi-auth | Auth type selector: pat, oauth_m2m, u2m_browser, u2m_custom_oauth, u2m_token_env |
Important: Do not mix M2M and U2M environment variables. Use env -i for clean test environments.
Complete Examples
PAT Authentication (Testing Only)
package main
import (
"database/sql"
"fmt"
"os"
"strings"
dbsql "github.com/databricks/databricks-sql-go"
)
func main() {
host := os.Getenv("DATABRICKS_HOST")
httpPath := os.Getenv("DATABRICKS_HTTP_PATH")
token := os.Getenv("DATABRICKS_TOKEN")
connector, err := dbsql.NewConnector(
dbsql.WithServerHostname(serverHostname(host)),
dbsql.WithPort(443),
dbsql.WithHTTPPath(httpPath),
dbsql.WithAccessToken(token),
dbsql.WithUserAgentEntry("YourCompany_YourProduct/1.0.0"),
)
if err != nil {
panic(err)
}
db := sql.OpenDB(connector)
defer db.Close()
rows, err := db.Query("SELECT COUNT(*) FROM samples.nyctaxi.trips")
if err != nil {
panic(err)
}
defer rows.Close()
var count int64
rows.Next()
rows.Scan(&count)
fmt.Printf("PAT OK: %d trips\n", count)
}
func serverHostname(host string) string {
s := strings.TrimPrefix(host, "https://")
s = strings.TrimPrefix(s, "http://")
if idx := strings.Index(s, "/"); idx >= 0 {
s = s[:idx]
}
return s
}
Env vars: DATABRICKS_HOST, DATABRICKS_HTTP_PATH, DATABRICKS_TOKEN
OAuth M2M Authentication (Production Recommended)
Uses the driver's built-in M2M authenticator that handles token fetch and refresh:
package main
import (
"database/sql"
"fmt"
"os"
"strings"
dbsql "github.com/databricks/databricks-sql-go"
"github.com/databricks/databricks-sql-go/auth/oauth/m2m"
)
func main() {
host := os.Getenv("DATABRICKS_HOST")
httpPath := os.Getenv("DATABRICKS_HTTP_PATH")
clientID := os.Getenv("DATABRICKS_CLIENT_ID")
clientSecret := os.Getenv("DATABRICKS_CLIENT_SECRET")
authenticator := m2m.NewAuthenticator(clientID, clientSecret, serverHostname(host))
connector, err := dbsql.NewConnector(
dbsql.WithServerHostname(serverHostname(host)),
dbsql.WithPort(443),
dbsql.WithHTTPPath(httpPath),
dbsql.WithAuthenticator(authenticator),
dbsql.WithUserAgentEntry("YourCompany_YourProduct/1.0.0"),
)
if err != nil {
panic(err)
}
db := sql.OpenDB(connector)
defer db.Close()
rows, err := db.Query("SELECT COUNT(*) FROM samples.nyctaxi.trips")
if err != nil {
panic(err)
}
defer rows.Close()
var count int64
rows.Next()
rows.Scan(&count)
fmt.Printf("OAuth M2M OK: %d trips\n", count)
}
func serverHostname(host string) string {
s := strings.TrimPrefix(host, "https://")
s = strings.TrimPrefix(s, "http://")
if idx := strings.Index(s, "/"); idx >= 0 {
s = s[:idx]
}
return s
}
Env vars: DATABRICKS_HOST, DATABRICKS_HTTP_PATH, DATABRICKS_CLIENT_ID, DATABRICKS_CLIENT_SECRET
Setup: Create service principal in Account Console → Settings → Service principals. Generate OAuth secret. Grant CAN_USE on the SQL warehouse.
U2M Browser Authentication (Driver-Native)
Uses the driver's built-in U2M authenticator that opens the user's default browser:
package main
import (
"database/sql"
"fmt"
"os"
"strings"
"time"
dbsql "github.com/databricks/databricks-sql-go"
"github.com/databricks/databricks-sql-go/auth/oauth/u2m"
)
func main() {
host := os.Getenv("DATABRICKS_HOST")
httpPath := os.Getenv("DATABRICKS_HTTP_PATH")
authenticator, err := u2m.NewAuthenticator(serverHostname(host), 2*time.Minute)
if err != nil {
panic(err)
}
connector, err := dbsql.NewConnector(
dbsql.WithServerHostname(serverHostname(host)),
dbsql.WithPort(443),
dbsql.WithHTTPPath(httpPath),
dbsql.WithAuthenticator(authenticator),
dbsql.WithUserAgentEntry("YourCompany_YourProduct/1.0.0"),
)
if err != nil {
panic(err)
}
db := sql.OpenDB(connector)
defer db.Close()
rows, err := db.Query("SELECT COUNT(*) FROM samples.nyctaxi.trips")
if err != nil {
panic(err)
}
defer rows.Close()
var count int64
rows.Next()
rows.Scan(&count)
fmt.Printf("U2M Browser OK: %d trips\n", count)
}
func serverHostname(host string) string {
s := strings.TrimPrefix(host, "https://")
s = strings.TrimPrefix(s, "http://")
if idx := strings.Index(s, "/"); idx >= 0 {
s = s[:idx]
}
return s
}
Env vars: DATABRICKS_HOST, DATABRICKS_HTTP_PATH
Notes:
- Uses Databricks' built-in OAuth app (client_id=
databricks-sql-connector)
- Do NOT set
DATABRICKS_CLIENT_ID or DATABRICKS_TOKEN
- Driver picks an available localhost port at runtime
U2M Token-Env Authentication (Headless/CI)
Pass a pre-obtained OAuth access token:
package main
import (
"database/sql"
"fmt"
"os"
"strings"
dbsql "github.com/databricks/databricks-sql-go"
)
func main() {
host := os.Getenv("DATABRICKS_HOST")
httpPath := os.Getenv("DATABRICKS_HTTP_PATH")
token := os.Getenv("DATABRICKS_ACCESS_TOKEN")
if token == "" {
token = os.Getenv("DATABRICKS_TOKEN")
}
connector, err := dbsql.NewConnector(
dbsql.WithServerHostname(serverHostname(host)),
dbsql.WithPort(443),
dbsql.WithHTTPPath(httpPath),
dbsql.WithAccessToken(token),
dbsql.WithUserAgentEntry("YourCompany_YourProduct/1.0.0"),
)
if err != nil {
panic(err)
}
db := sql.OpenDB(connector)
defer db.Close()
rows, err := db.Query("SELECT COUNT(*) FROM samples.nyctaxi.trips")
if err != nil {
panic(err)
}
defer rows.Close()
var count int64
rows.Next()
rows.Scan(&count)
fmt.Printf("U2M Token-Env OK: %d trips\n", count)
}
func serverHostname(host string) string {
s := strings.TrimPrefix(host, "https://")
s = strings.TrimPrefix(s, "http://")
if idx := strings.Index(s, "/"); idx >= 0 {
s = s[:idx]
}
return s
}
Env vars: DATABRICKS_HOST, DATABRICKS_HTTP_PATH, DATABRICKS_ACCESS_TOKEN (or DATABRICKS_TOKEN)
U2M Custom OAuth App (PKCE) - Interactive
For user-interactive flows with a custom OAuth app:
package main
import (
"context"
"crypto/rand"
"crypto/sha256"
"database/sql"
"encoding/base64"
"encoding/json"
"fmt"