Apache Impala driver for Go's database/sql package
This driver started as a fork of github.com/bippio/go-impala, which hasn't been updated in over four years and appears to be abandoned. After fork, several issues have been fixed.
The current implementation of the driver is based on the Hive Server 2 protocol. Issues and contributions are welcome.
go get github.com/sclgo/impala
The connection string uses a URL format: impala://username:password@host:port?param1=value¶m2=value
auth
- string. Authentication mode. Supported values: "noauth", "ldap"tls
- boolean. Enable TLSca-cert
- The file that contains the public key certificate of the CA that signed the impala certificatebatch-size
- integer value (default: 1024). Maximum number of rows fetched per requestbuffer-size
- in bytes (default: 4096); Buffer size for the Thrift transportmem-limit
- string value (example: 3m); Memory limit for query
A string of this format can be constructed using the URL type in the net/url package.
query := url.Values{}
query.Add("auth", "ldap")
u := &url.URL{
Scheme: "impala",
User: url.UserPassword(username, password),
Host: net.JoinHostPort(hostname, port),
RawQuery: query.Encode(),
}
db, err := sql.Open("impala", u.String())
Also, you can bypass string-base data source name by using sql.OpenDB:
opts := impala.DefaultOptions
opts.Host = hostname
opts.UseLDAP = true
opts.Username = username
opts.Password = password
connector := impala.NewConnector(&opts)
db := sql.OpenDB(connector)
package main
// Simple program to list databases and the tables
import (
"context"
"database/sql"
"log"
"github.com/sclgo/impala"
)
func main() {
opts := impala.DefaultOptions
opts.Host = "<impala host>"
opts.Port = "21050"
// enable LDAP authentication:
opts.UseLDAP = true
opts.Username = "<ldap username>"
opts.Password = "<ldap password>"
// enable TLS
opts.UseTLS = true
opts.CACertPath = "/path/to/cacert"
connector := impala.NewConnector(&opts)
db := sql.OpenDB(connector)
defer db.Close()
ctx := context.Background()
rows, err := db.QueryContext(ctx, "SHOW DATABASES")
if err != nil {
log.Fatal(err)
}
r := struct {
name string
comment string
}{}
databases := make([]string, 0) // databases will contain all the DBs to enumerate later
for rows.Next() {
if err := rows.Scan(&r.name, &r.comment); err != nil {
log.Fatal(err)
}
databases = append(databases, r.name)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
log.Println("List of Databases", databases)
stmt, err := db.PrepareContext(ctx, "SHOW TABLES IN ?")
if err != nil {
log.Fatal(err)
}
tbl := struct {
name string
}{}
for _, d := range databases {
rows, err := stmt.QueryContext(ctx, d)
if err != nil {
log.Printf("error in querying database %s: %s", d, err.Error())
continue
}
tables := make([]string, 0)
for rows.Next() {
if err := rows.Scan(&tbl.name); err != nil {
log.Println(err)
continue
}
tables = append(tables, tbl.name)
}
log.Printf("List of Tables in Database %s: %v\n", d, tables)
}
}