Partilhar via


Databricks SQL Driver for Go

O Databricks SQL Driver for Go é uma biblioteca Go que permite usar o código Go para executar comandos SQL nos recursos de computação do Azure Databricks. Este artigo complementa o Databricks SQL Driver for Go README, referência de API e exemplos.

Requisitos

Introdução ao Databricks SQL Driver for Go

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

    go mod init sample
    
  2. Dependa do pacote Databricks SQL Driver for Go executando o go mod edit -require comando, 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
    

    O seu go.mod ficheiro deve agora ter o seguinte aspeto:

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

    go mod tidy
    

    Nota

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

  5. Faça cópias de todos os pacotes necessários para suportar compilações e testes de pacotes em seu main módulo, executando o go mod vendor comando:

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

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

    go run main.go
    
  8. Se nenhum erro for retornado, você autenticou com êxito o Databricks SQL Driver for Go com seu espaço de trabalho do Azure Databricks e se conectou ao cluster do Azure Databricks ou ao SQL warehouse em execução nesse espaço de trabalho.

Conectar-se com uma cadeia de conexão DSN

Para acessar clusters e SQL warehouses, use sql.Open() para criar um identificador de banco de dados por meio de uma cadeia de conexão de nome de fonte de dados (DSN). Este exemplo de código recupera a cadeia 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 a cadeia de conexão DSN no formato correto, consulte os exemplos de cadeia de conexão DSN em Autenticação. Por exemplo, para autenticação de token de acesso pessoal do Azure Databricks, use a seguinte sintaxe, onde:

  • <personal-access-token> é o seu token de acesso pessoal do Azure Databricks a partir dos requisitos.
  • <server-hostname> é o valor Server Hostname 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 cluster:

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

Por exemplo, para um armazém SQL:

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

Nota

Como prática recomendada de segurança, você não deve codificar essa cadeia de conexão DSN em seu código Go. Em vez disso, você deve recuperar essa cadeia de conexão DSN de um local seguro. Por exemplo, o exemplo de código anteriormente 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 utilizados 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. A predefinição é 10000.
    • timeout: Adiciona o tempo limite (em segundos) para a execução da consulta ao servidor. O padrão é sem tempo limite.
    • userAgentEntry: Usado para identificar parceiros. Para obter mais informações, consulte a documentação do seu parceiro.
  • Os parâmetros de sessão opcionais suportados podem ser especificados em param=value. Alguns dos mais utilizados incluem:
    • ansi_mode: Uma corda booleana. true para instruções de sessão para aderir às regras especificadas pela especificação ANSI SQL. O padrão do sistema é false.
    • timezone: Uma cadeia de caracteres, por exemplo America/Los_Angeles. Define o fuso horário da sessão. O padrão do sistema é UTC.

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

Conecte-se com a NewConnector função

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 do Azure Databricks e armazéns SQL 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 NewConnector configurações, consulte os exemplos em Autenticação.

Nota

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

Algumas das opções funcionais mais utilizadas incluem:

  • WithAccessToken(<access-token>): Seu token de acesso pessoal do Azure Databricks dos requisitos. Obrigatório string.
  • WithServerHostname(<server-hostname>): O valor Server Hostname 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. Opcionalstring, string.
  • WithMaxRows(<max-rows>): O número máximo de linhas buscadas por solicitação. O padrão é 10000. Opcional int.
  • WithSessionParams(<params-map>): Os parâmetros da sessão, incluindo "fuso horário" e "ansi_mode". Opcionalmap[string]string.
  • WithTimeout(<timeout>). O tempo limite (em time.Duration) para a execução da consulta do servidor. O padrão é sem tempo limite. Opcional.
  • WithUserAgentEntry(<isv-name-plus-product-name>). Usado para identificar parceiros. Para obter mais informações, consulte a documentação do seu parceiro. Opcionalstring.

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 Azure Databricks:

O Databricks SQL Driver for Go ainda não oferece suporte aos seguintes tipos de autenticação do Azure Databricks:

Autenticação de token de acesso pessoal Databricks

Para usar o Databricks SQL Driver for Go com a autenticação de token de acesso pessoal do Azure Databricks, você deve primeiro criar um token de acesso pessoal do Azure Databricks, da seguinte maneira:

  1. No seu espaço de trabalho do Azure Databricks, clique no seu nome de utilizador do Azure Databricks na barra superior e, em seguida, selecione Definições na lista pendente.
  2. Clique em Desenvolvedor.
  3. Ao lado de Tokens de acesso, clique em Gerenciar.
  4. Clique em Gerar novo token.
  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 tempo de vida (não recomendado), deixe a caixa Tempo de vida (dias) vazia (em branco).
  6. Clique em Generate (Gerar).
  7. Copie o token exibido para um local seguro e clique em Concluído.

Nota

Certifique-se de salvar o token copiado em um local seguro. Não partilhe o seu token copiado com outras pessoas. Se você perder o token copiado, não poderá regenerar exatamente o mesmo token. Em vez disso, você deve repetir esse procedimento para criar um novo token. Se você perder o token copiado ou acreditar que o token foi comprometido, o Databricks recomenda que você exclua imediatamente esse token do seu espaço de trabalho clicando no ícone da lixeira (Revogar) ao lado do token na página de tokens do Access.

Se você não conseguir criar ou usar tokens em seu espaço de trabalho, isso pode ser porque o administrador do espaço de trabalho desabilitou tokens ou não lhe deu permissão para criar ou usar tokens. Consulte o administrador do espaço de trabalho ou o seguinte:

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

  • <personal-access-token> é o seu token de acesso pessoal do Azure Databricks a partir dos requisitos.
  • <server-hostname> é o valor Server Hostname 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 acrescentar 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 NewConnector função, use o seguinte trecho de código e o exemplo de código em Connect with the NewConnector function, que pressupõe que você tenha definido as seguintes variáveis de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor Nome do host do servidor para seu cluster ou SQL warehouse.
  • DATABRICKS_HTTP_PATH, definido como o valor Caminho HTTP para seu cluster ou SQL warehouse.
  • DATABRICKS_TOKEN, definido como o token de acesso pessoal do Azure Databricks.

Para definir variáveis de ambiente, consulte a documentação do seu 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 token Microsoft Entra ID (anteriormente Azure Ative Directory)

O Databricks SQL Driver for Go dá suporte a tokens Microsoft Entra ID (anteriormente Azure Ative Directory) para um usuário do Azure Databricks ou uma entidade de serviço Microsoft Entra ID.

Para criar um token de acesso do Microsoft Entra ID, faça o seguinte:

  • Para um usuário do Azure Databricks, você pode usar a CLI do Azure. Consulte Obter tokens do Microsoft Entra ID (anteriormente Azure Ative Directory) para usuários usando a CLI do Azure.

    Os tokens Microsoft Entra ID têm um tempo de vida padrão de cerca de 1 hora. Para criar um novo token de ID do Microsoft Entra, repita este processo.

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

    • <microsoft-entra-id-token> é o seu token de ID do Microsoft Entra.
    • <server-hostname> é o valor Server Hostname 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 acrescentar um ou mais parâmetros opcionais listados anteriormente neste artigo.

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

    Para autenticar o Databricks SQL Driver for Go com a NewConnector função, use o seguinte trecho de código e o exemplo de código em Connect with the NewConnector function, que pressupõe que você tenha definido as seguintes variáveis de ambiente:

    • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor Nome do host do servidor para seu cluster ou SQL warehouse.
    • DATABRICKS_HTTP_PATH, definido como o valor Caminho HTTP para seu cluster ou SQL warehouse.
    • DATABRICKS_TOKEN, definido como seu token de ID do Microsoft Entra.

    Para definir variáveis de ambiente, consulte a documentação do seu 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 OAuth user-to-machine (U2M)

O Databricks SQL Driver for Go versões 1.5.0 e superiores suporta autenticação OAuth user-to-machine (U2M).

Para usar o Databricks SQL Driver for Go com uma cadeia de conexão DSN e o exemplo de código em Conectar com uma cadeia de conexão DSN, use a seguinte sintaxe de cadeia de conexão DSN, onde:

  • <server-hostname> é o valor Server Hostname 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 acrescentar 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 NewConnector função, você deve primeiro adicionar o seguinte à sua import declaração:

"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 with the NewConnector function, que pressupõe que você tenha definido as seguintes variáveis de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor Nome do host do servidor para seu cluster ou SQL warehouse.
  • DATABRICKS_HTTP_PATH, definido como o valor Caminho HTTP para seu cluster ou SQL warehouse.

Para definir variáveis de ambiente, consulte a documentação do seu 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)

O Databricks SQL Driver for Go versões 1.5.2 e superiores suporta autenticação OAuth máquina-a-máquina (M2M).

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 Azure Databricks em seu espaço de trabalho do Azure Databricks e crie um segredo OAuth para essa entidade de serviço.

    Para criar a entidade de serviço e seu segredo OAuth, consulte Usar uma entidade de serviço para autenticar com o Azure Databricks. Anote o valor UUID ou ID do aplicativo da entidade de serviço e o valor Secret do segredo OAuth da entidade de serviço.

  2. Dê a essa entidade de serviço acesso ao seu cluster ou depósito.

    Para conceder à entidade de serviço acesso ao cluster ou depósito, consulte Permissões de computação ou Gerenciar um depósito SQL.

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

  • <server-hostname> é o valor Server Hostname 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 Secret para o segredo OAuth da entidade de serviço.

Você também pode acrescentar 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 NewConnector função, você deve primeiro adicionar o seguinte à sua import declaração:

"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 with the NewConnector function, que pressupõe que você tenha definido as seguintes variáveis de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor Nome do host do servidor para seu cluster ou SQL warehouse.
  • DATABRICKS_HTTP_PATH, definido como o valor Caminho HTTP para seu cluster ou SQL warehouse.
  • DATABRICKS_CLIENT_ID, definido como o valor UUID ou ID do aplicativo da entidade de serviço.
  • DATABRICKS_CLIENT_SECRET, definido como o valor Secret para o segredo OAuth da entidade de serviço.

Para definir variáveis de ambiente, consulte a documentação do seu 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 os dados

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

Este exemplo de código recupera a cadeia de 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)
  }
}

Gerenciar arquivos em volumes do Catálogo Unity

O Databricks SQL Driver permite que você escreva arquivos locais em volumes do Catálogo Unity, baixe arquivos de volumes e exclua arquivos de volumes, conforme mostrado no exemplo a seguir:

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

Registo

Use github.com/databricks/databricks-sql-go/logger para registrar mensagens que o Databricks SQL Driver for 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 a cadeia de conexão DSN de uma variável de ambiente chamada DATABRICKS_DSN. Todas as mensagens de log que são emitidas no nível e abaixo são gravadas no debug results.log arquivo.

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

Testar

Para testar seu código, use estruturas de teste Go, como a biblioteca padrão de teste . Para testar seu código em condições simuladas sem chamar pontos de extremidade da API REST do Azure Databricks ou alterar o estado de suas contas ou espaços de trabalho do Azure Databricks, use bibliotecas simuladas Go como testfify.

Por exemplo, dado o seguinte arquivo chamado helpers.go contendo uma GetDBWithDSNPAT função que retorna uma conexão de espaço de trabalho do Azure Databricks, uma GetNYCTaxiTrips função que retorna dados da trips tabela no samples esquema do nyctaxi catálogo e uma PrintNYCTaxiTrips que imprime os dados retornados:

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

E dado o seguinte arquivo chamado main.go que chama essas funções:

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

O arquivo a seguir chamado helpers_test.go testa se a GetNYCTaxiTrips função retorna a resposta esperada. Em vez de criar uma conexão real com o espaço de trabalho de destino, esse teste simula um sql.DB objeto. O teste também simula alguns dados que estão em conformidade com o esquema e os valores que estão nos dados reais. O teste retorna os dados simulados por meio da conexão simulada e, em seguida, verifica se um dos valores das linhas de dados simuladas corresponde ao valor esperado.

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

Como a GetNYCTaxiTrips função contém uma SELECT instrução e, portanto, não altera o estado da tabela, a trips simulação não é absolutamente necessária neste exemplo. No entanto, a simulação permite que você execute rapidamente seus testes sem esperar que uma conexão real seja feita com o espaço de trabalho. Além disso, a simulação permite que você execute testes simulados várias vezes para funções que podem alterar o estado de uma tabela, como INSERT INTO, UPDATEe DELETE FROM.

Recursos adicionais