Databricks SQL Driver para Go

O Databricks SQL Driver for Go é uma biblioteca Go que permite usar o código Go para executar o comando SQL no recurso compute do Databricks. Este artigo complementa o README do Databricks SQL Driver for Go, referência de API e exemplos.

Requisitos

Começando com o Databricks SQL Driver for Go

  1. Na sua máquina de desenvolvimento com Go 1.20 ou acima já instalado e um projeto de código Go existente já criado, crie um arquivo go.mod para rastrear as dependências do seu código Go executando o comando go mod init , por exemplo:

    go mod init sample
    
  2. Assuma uma dependência do pacote Databricks SQL Driver for Go executando o comando go mod edit -require , substituindo v1.5.2 pela versão mais recente do pacote Databricks SQL Driver for Go conforme listado nas versões:

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

    Seu arquivo go.mod agora deve ficar assim:

    module sample
    
    go 1.20
    
    require github.com/databricks/databricks-sql-go v1.5.2
    
  3. No seu projeto, crie um arquivo de código Go que importe o Databricks SQL Driver for Go. O exemplo a seguir, em um arquivo chamado main.go com o conteúdo a seguir, lista todos os clusters em seu workspace do 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. Adicione quaisquer dependências de módulo ausentes executando o comando go mod tidy :

    go mod tidy
    

    Observação

    Se receber o erro go: warning: "all" matched no packages, você se esqueceu de adicionar um arquivo de código Go que importa o driver Databricks SQL para Go.

  5. Faça cópias de todo o pacote necessário para dar suporte a compilações e testes de pacote no módulo main , executando o comando go mod vendor :

    go mod vendor
    
  6. Modifique seu código conforme necessário para definir a variável de ambiente DATABRICKS_DSN para autenticação do Databricks. Consulte também Conectar-se com stringsde conexão DSN.

  7. Execute seu arquivo de código Go, assumindo um arquivo chamado main.go, executando o comando go run :

    go run main.go
    
  8. Se nenhum erro for retornado, você autenticou com êxito o Databricks SQL Driver for Go com seu workspace do Databricks e conectou-se aos clusters do Databricks em execução ou SQL warehouse nesse workspace.

Conectar com stringsde conexão DSN

Para acessar clusters e SQL warehouse, use sql.Open() para criar um identificador de banco de dados por meio de strings de conexão de nome de fonte de dados (DSN). Este exemplo de código recupera as strings de conexão DSN de uma variável de ambiente chamada DATABRICKS_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)
  }
}

Para especificar as strings de conexão DSN no formato correto, consulte os exemplos strings de conexão DSN em Autenticação. Por exemplo, para autenticação access token pessoal do Databricks, use a seguinte sintaxe, onde:

  • <personal-access-token> são seus access tokens pessoal do Databricks dos requisitos.

  • <server-hostname> é o valor hostnamedo servidor dos requisitos.

  • <port-number> é o valor da porta dos requisitos, que normalmente é 443.

  • <http-path> é o valor do Caminho HTTP dos requisitos.

  • <paramX=valueX> é um ou mais parâmetros opcionais listados posteriormente neste artigo.

token:<personal-access-token>@<server-hostname>:<port-number>/<http-path>?<param1=value1>&<param2=value2>

Por exemplo, para um clusters:

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

Por exemplo, para um SQL warehouse:

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

Observação

Como prática recomendada de segurança, você não deve codificar essas strings de conexão DSN em seu código Go. Em vez disso, você deve recuperar essas strings de conexão DSN de um local seguro. Por exemplo, o exemplo de código anterior neste artigo usou uma variável de ambiente.

Parâmetros opcionais

  • Os parâmetros de conexão opcionais suportados podem ser especificados em <param=value>. Alguns dos mais usados incluem:

    • catalog: define o nome do catálogo inicial na sessão.

    • schema: define o nome do esquema inicial na sessão.

    • maxRows: configura o número máximo de linhas buscadas por solicitação. O default é 10000.

    • timeout: Adiciona o tempo limite (em segundos) para a execução query do servidor. O default é sem tempo limite.

    • userAgentEntry: Usado para identificar parceiros. Para mais informações, consulte a documentação de seus parceiros.

  • Os parâmetros de sessão opcionais suportados podem ser especificados em param=value. Alguns dos mais usados incluem:

    • ansi_mode: Uma strings Boolean. true para instruções de sessão aderirem às regras especificadas pela especificação ANSI SQL. O default do sistema é falso.

    • timezone: A strings, por exemplo America/Los_Angeles. Define o fuso horário da sessão. O default do sistema é UTC.

Por exemplo, para um 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

Conecte-se com a função NewConnector

Como alternativa, use sql.OpenDB() para criar um identificador de banco de dados por meio de um novo objeto de conector criado com dbsql.NewConnector() (conectar-se a clusters Databricks e SQL warehouse com um novo objeto de conector requer v1.0.0 ou superior do Databricks SQL Driver for Go) . Por exemplo:

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

Para especificar o conjunto correto de configurações NewConnector , consulte os exemplos em Autenticação.

Observação

Como prática recomendada de segurança, você não deve codificar suas configurações NewConnector em seu código Go. Em vez disso, você deve recuperar esses valores de um local seguro. Por exemplo, o código anterior usa variável de ambiente.

Algumas das opções funcionais usadas com mais frequência incluem:

  • WithAccessToken(<access-token>): Seu access token pessoal do Databricks dos requisitos. Obrigatório string.

  • WithServerHostname(<server-hostname>): o valor hostnamedo servidor dos requisitos. Obrigatório string.

  • WithPort(<port>): o número da porta do servidor, normalmente 443. Obrigatório int.

  • WithHTTPPath(<http-path>): o valor do caminho HTTP dos requisitos. Obrigatório string.

  • WithInitialNamespace(<catalog>, <schema>):O nome do catálogo e do esquema na sessão. Opcional string, string.

  • WithMaxRows(<max-rows>): o número máximo de linhas buscadas por solicitação. O default é 10000. Opcional int.

  • WithSessionParams(<params-map>): Os parâmetros da sessão, incluindo “fuso horário” e “ansi_mode”. Opcional map[string]string.

  • WithTimeout(<timeout>). O tempo limite (em time.Duration) para a execução query do servidor. O default é sem tempo limite. Opcional.

  • WithUserAgentEntry(<isv-name-plus-product-name>). Usado para identificar parceiros. Para mais informações consulte a documentação dos seus parceiros. Opcional string.

Por exemplo:

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

Autenticação

O Databricks SQL Driver for Go dá suporte aos seguintes tipos de autenticação do Databricks:

O Databricks SQL Driver for Go não oferece suporte à autenticação de nome de usuário e senha do Databricks (também conhecida como básica).

Autenticação de token de acesso pessoal do Databricks

Para usar o Databricks SQL Driver para Go com autenticação access token pessoal do Databricks, você deve primeiro criar um access token pessoal do Databricks, da seguinte forma:

  1. No workspace do Databricks, clique no nome de usuário do Databricks na barra superior e selecione Configurações do usuário na lista suspensa.

  2. Clique em Desenvolvedor.

  3. Ao lado do access token, clique em gerenciar.

  4. Clique em Gerar novos tokens.

  5. (Opcional) Insira um comentário que o ajude a identificar esse token no futuro e altere o tempo de vida padrão do token de 90 dias. Para criar um token sem vida útil (não recomendado), deixe a caixa Duração (dias) vazia (em branco).

  6. Clique em Gerar.

  7. Copie o token exibido em um local seguro e clique em Concluído.

Observação

Certifique-se de salvar os tokens copiados em um local seguro. Não compartilhe seus tokens copiados com outras pessoas. Se você perder os tokens copiados, não poderá regenerar exatamente os mesmos tokens. Em vez disso, você deve repetir este procedimento para criar novos tokens. Se você perder os tokens copiados ou acreditar que os tokens foram comprometidos, o Databricks recomenda fortemente que você exclua imediatamente esses tokens do seu workspace clicando no ícone da lixeira (Revogar) ao lado dos tokens na página access tokens .

Se não for possível criar ou usar tokens no seu workspace, isso pode ocorrer porque o administrador do workspace desativou os tokens ou não lhe deu permissão para criar ou usar tokens. Consulte o administrador do workspace ou o seguinte:

Para autenticar o Databricks SQL Driver for Go com strings de conexão DSN e o exemplo de código em Connect with a DSN connection strings, use a seguinte sintaxe de strings de conexão DSN, onde:

  • <personal-access-token> são seus access tokens pessoal do Databricks dos requisitos.

  • <server-hostname> é o valor hostnamedo servidor dos requisitos.

  • <port-number> é o valor da porta dos requisitos, que normalmente é 443.

  • <http-path> é o valor do Caminho HTTP dos requisitos.

Você também pode anexar um ou mais parâmetros opcionais listados anteriormente neste artigo.

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

Para autenticar o Databricks SQL Driver for Go com a função NewConnector , use o seguinte trecho de código e o exemplo de código em Connect com a função NewConnector, que pressupõe que você definiu a seguinte variável de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor hostnamedo servidor para seus clusters ou SQL warehouse.

  • DATABRICKS_HTTP_PATH, defina o valor do Caminho HTTP para seus clusters ou SQL warehouse.

  • DATABRICKS_TOKEN, defina como o access token pessoal do Databricks.

Para definir variáveis de ambiente, consulte a documentação do sistema operacional.

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

Autenticação de usuário para máquina (U2M) OAuth

Databricks SQL Driver for Go versões 1.5.0 e acima suportam autenticação OAuth usuário-máquina (U2M).

Para usar o Databricks SQL Driver for Go com strings de conexão DSN e o exemplo de código em Connect with a DSN connection strings, use a seguinte sintaxe de strings de conexão DSN, onde:

  • <server-hostname> é o valor hostnamedo servidor dos requisitos.

  • <port-number> é o valor da porta dos requisitos, que normalmente é 443.

  • <http-path> é o valor do Caminho HTTP dos requisitos.

Você também pode anexar um ou mais parâmetros opcionais listados anteriormente neste artigo.

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

Para autenticar o Databricks SQL Driver for Go com a função NewConnector , você deve primeiro adicionar o seguinte à sua declaração import :

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

Em seguida, use o seguinte trecho de código e o exemplo de código em Connect com a função NewConnector, que pressupõe que você tenha definido a seguinte variável de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor hostnamedo servidor para seus clusters ou SQL warehouse.

  • DATABRICKS_HTTP_PATH, defina o valor do Caminho HTTP para seus clusters ou SQL warehouse.

Para definir variáveis de ambiente, consulte a documentação do sistema operacional.

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

Autenticação OAuth máquina a máquina (M2M)

Databricks SQL Driver for Go versões 1.5.2 e acima suportam autenticação máquina a máquina (M2M) OAuth.

Para usar o Databricks SQL Driver for Go com autenticação OAuth M2M, você deve fazer o seguinte:

  1. Crie uma entidade de serviço do Databricks em seu workspace do Databricks e crie um segredo OAuth para essa entidade de serviço.

    Para criar a entidade de serviço e seu segredo OAuth, consulte Autenticação OAuth máquina a máquina (M2M). Anote o valor do UUID da entidade de serviço ou do ID do aplicativo e o valor do segredo do OAuth da entidade de serviço.

  2. Dê a essa entidade de serviço acesso aos seus clusters ou warehouse.

    Para conceder à entidade de serviço acesso ao seu cluster ou depósito, consulte compute permissions ou gerenciar a SQL warehouse.

Para autenticar o Databricks SQL Driver for Go com strings de conexão DSN e o exemplo de código em Connect with a DSN connection strings, use a seguinte sintaxe de strings de conexão DSN, onde:

  • <server-hostname> é o valor hostnamedo servidor dos requisitos.

  • <port-number> é o valor da porta dos requisitos, que normalmente é 443.

  • <http-path> é o valor do Caminho HTTP dos requisitos.

  • <client-id> é o valor UUID ou ID do aplicativo da entidade de serviço.

  • <client-secret> é o valor secreto do segredo OAuth da entidade de serviço.

Você também pode anexar um ou mais parâmetros opcionais listados anteriormente neste artigo.

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

Para autenticar o Databricks SQL Driver for Go com a função NewConnector , você deve primeiro adicionar o seguinte à sua declaração import :

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

Em seguida, use o seguinte trecho de código e o exemplo de código em Connect com a função NewConnector, que pressupõe que você tenha definido a seguinte variável de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor hostnamedo servidor para seus clusters ou SQL warehouse.

  • DATABRICKS_HTTP_PATH, defina o valor do Caminho HTTP para seus clusters ou SQL warehouse.

  • DATABRICKS_CLIENT_ID, defina como o valor UUID ou ID do aplicativo da entidade de serviço.

  • DATABRICKS_CLIENT_SECRET, definido como o valor Secreto para o segredo OAuth da entidade de serviço.

Para definir variáveis de ambiente, consulte a documentação do sistema operacional.

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

Consultar dados

O exemplo de código a seguir demonstra como chamar o Databricks SQL Driver para Go para execução de uma query SQL básica em um recurso compute do Databricks. Este comando retorna as duas primeiras linhas da tabela trips no esquema nyctaxi do catálogo samples .

Este exemplo de código recupera as stringsde conexão DSN de uma variável de ambiente chamada DATABRICKS_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)
  }
}

Saída:

tpep_pickup_datetime,tpep_dropoff_datetime,trip_distance,fare_amount,pickup_zip,dropoff_zip
2016-02-14 16:52:13 +0000 UTC,2016-02-14 17:16:04 +0000 UTC,4.94,19,10282,10171
2016-02-04 18:44:19 +0000 UTC,2016-02-04 18:46:00 +0000 UTC,0.28,3.5,10110,10110

Para obter exemplos adicionais, consulte a pasta de exemplos no repositório databricks/databricks-sql-go no GitHub.

Registro em log

Use github.com/databricks/databricks-sql-go/logger para log mensagens que o driver Databricks SQL para Go emite. O exemplo de código a seguir usa sql.Open() para criar um identificador de banco de dados por meio de uma cadeia de conexão DSN. Este exemplo de código recupera as cadeias de conexão DSN de uma variável de ambiente denominada DATABRICKS_DSN. Todas as mensagens do site log emitidas no nível debug e abaixo são gravadas no arquivo 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)
  }
}

Recursos adicionais