Skip to content

Instantly share code, notes, and snippets.

@vdparikh
Created March 14, 2019 17:46
Show Gist options
  • Save vdparikh/491e22d46cbff522bc47cb8cedc88a8c to your computer and use it in GitHub Desktop.
Save vdparikh/491e22d46cbff522bc47cb8cedc88a8c to your computer and use it in GitHub Desktop.
simple snowflake database query from Go and return results as JSON
package main
import (
"database/sql"
"encoding/json"
"log"
"reflect"
"time"
sf "github.com/snowflakedb/gosnowflake"
"fmt"
)
var (
sfClient *sql.DB
)
type Config struct {
Account string
Region string
Warehouse string
Database string
Username string
Password string
}
func NewSnowflakeConnection(config Config) *sql.DB {
configStr, err := sf.DSN(&sf.Config{
Region: config.Region,
Account: config.Account,
User: config.Username,
Password: config.Password,
Database: config.Database,
Warehouse: config.Warehouse,
LoginTimeout: 5 * time.Second,
})
if err != nil {
log.Fatal(err)
}
db, err := sql.Open("snowflake", configStr)
if err != nil {
log.Fatal(err)
}
return db
}
func ResultsToJSON(rows *sql.Rows) ([]byte, error) {
var objects []map[string]interface{}
for rows.Next() {
columns, err := rows.ColumnTypes()
if err != nil {
return nil, err
}
// Scan needs an array of pointers to the values it is setting
// This creates the object and sets the values correctly
values := make([]interface{}, len(columns))
object := map[string]interface{}{}
for i, column := range columns {
object[column.Name()] = reflect.New(column.ScanType()).Interface()
values[i] = object[column.Name()]
}
err = rows.Scan(values...)
if err != nil {
return nil, err
}
objects = append(objects, object)
}
return json.Marshal(objects)
}
func main() {
sfClient = NewSnowflakeConnection(Config{
Account: "account_name",
Region: "us-east-1",
Username: "user",
Password: "password",
Database: "databots",
Warehouse: "demo_warehouse",
})
defer sfClient.Close()
err := sfClient.Ping()
if err != nil {
log.Fatal("Snowflake Connection not available")
return
}
rows, err := sfClient.Query("select * from TABLE_NM limit 10")
defer rows.Close()
if err != nil {
log.Fatal("ERROR: %s.", err)
}
b, err := ResultsToJSON(rows)
if err != nil {
log.Fatal("ERROR: %s.", err)
}
fmt.Println(string(b))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment