|  | ||
|---|---|---|
| .. | ||
| lib | ||
| .gitignore | ||
| .travis.yml | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
| array.go | ||
| bootstrap.go | ||
| clickhouse.go | ||
| clickhouse_exception.go | ||
| clickhouse_ping.go | ||
| clickhouse_profile_info.go | ||
| clickhouse_progress.go | ||
| clickhouse_read_block.go | ||
| clickhouse_read_meta.go | ||
| clickhouse_send_query.go | ||
| clickhouse_write_block.go | ||
| connect.go | ||
| docker-compose.yml | ||
| go.mod | ||
| go.sum | ||
| go.test.sh | ||
| helpers.go | ||
| query_settings.go | ||
| result.go | ||
| rows.go | ||
| stmt.go | ||
| tls_config.go | ||
| word_matcher.go | ||
| write_column.go | ||
		
			
				
				README.md
			
		
		
			
			
		
	
	ClickHouse  
  
 
Golang SQL database driver for Yandex ClickHouse
Key features
- Uses native ClickHouse tcp client-server protocol
- Compatibility with database/sql
- Round Robin load-balancing
- Bulk write support :  begin->prepare->(in loop exec)->commit
- LZ4 compression support (default to use pure go lz4, switch to use cgo lz4 by turn clz4 build tags on)
DSN
- username/password - auth credentials
- database - select the current default database
- read_timeout/write_timeout - timeout in second
- no_delay - disable/enable the Nagle Algorithm for tcp socket (default is 'true' - disable)
- alt_hosts - comma separated list of single address host for load-balancing
- connection_open_strategy - random/in_order (default random).
- random - choose random server from set
- in_order - first live server is choosen in specified order
 
- block_size - maximum rows in block (default is 1000000). If the rows are larger then the data will be split into several blocks to send them to the server
- pool size - maximum amount of preallocated byte chunks used in queries (default is 100). Decrease this if you experience memory problems at the expense of more GC pressure and vice versa.
- debug - enable debug output (boolean value)
SSL/TLS parameters:
- secure - establish secure connection (default is false)
- skip_verify - skip certificate verification (default is false)
- tls_config - name of a TLS config with client certificates, registered using clickhouse.RegisterTLSConfig(); implies secure to be true, unless explicitly specified
example:
tcp://host1:9000?username=user&password=qwerty&database=clicks&read_timeout=10&write_timeout=20&alt_hosts=host2:9000,host3:9000
Supported data types
- UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64
- Float32, Float64
- String
- FixedString(N)
- Date
- DateTime
- IPv4
- IPv6
- Enum
- UUID
- Nullable(T)
- Array(T) (one-dimensional) godoc
TODO
- Support other compression methods(zstd ...)
Install
go get -u github.com/kshvakov/clickhouse
Example
package main
import (
	"database/sql"
	"fmt"
	"log"
	"time"
	"github.com/kshvakov/clickhouse"
)
func main() {
	connect, err := sql.Open("clickhouse", "tcp://127.0.0.1:9000?debug=true")
	if err != nil {
		log.Fatal(err)
	}
	if err := connect.Ping(); err != nil {
		if exception, ok := err.(*clickhouse.Exception); ok {
			fmt.Printf("[%d] %s \n%s\n", exception.Code, exception.Message, exception.StackTrace)
		} else {
			fmt.Println(err)
		}
		return
	}
	_, err = connect.Exec(`
		CREATE TABLE IF NOT EXISTS example (
			country_code FixedString(2),
			os_id        UInt8,
			browser_id   UInt8,
			categories   Array(Int16),
			action_day   Date,
			action_time  DateTime
		) engine=Memory
	`)
	if err != nil {
		log.Fatal(err)
	}
	var (
		tx, _   = connect.Begin()
		stmt, _ = tx.Prepare("INSERT INTO example (country_code, os_id, browser_id, categories, action_day, action_time) VALUES (?, ?, ?, ?, ?, ?)")
	)
	defer stmt.Close()
	for i := 0; i < 100; i++ {
		if _, err := stmt.Exec(
			"RU",
			10+i,
			100+i,
			clickhouse.Array([]int16{1, 2, 3}),
			time.Now(),
			time.Now(),
		); err != nil {
			log.Fatal(err)
		}
	}
	if err := tx.Commit(); err != nil {
		log.Fatal(err)
	}
	rows, err := connect.Query("SELECT country_code, os_id, browser_id, categories, action_day, action_time FROM example")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	for rows.Next() {
		var (
			country               string
			os, browser           uint8
			categories            []int16
			actionDay, actionTime time.Time
		)
		if err := rows.Scan(&country, &os, &browser, &categories, &actionDay, &actionTime); err != nil {
			log.Fatal(err)
		}
		log.Printf("country: %s, os: %d, browser: %d, categories: %v, action_day: %s, action_time: %s", country, os, browser, categories, actionDay, actionTime)
	}
	if _, err := connect.Exec("DROP TABLE example"); err != nil {
		log.Fatal(err)
	}
}
Use sqlx
package main
import (
	"log"
	"time"
	"github.com/jmoiron/sqlx"
	_ "github.com/kshvakov/clickhouse"
)
func main() {
	connect, err := sqlx.Open("clickhouse", "tcp://127.0.0.1:9000?debug=true")
	if err != nil {
		log.Fatal(err)
	}
	var items []struct {
		CountryCode string    `db:"country_code"`
		OsID        uint8     `db:"os_id"`
		BrowserID   uint8     `db:"browser_id"`
		Categories  []int16   `db:"categories"`
		ActionTime  time.Time `db:"action_time"`
	}
	if err := connect.Select(&items, "SELECT country_code, os_id, browser_id, categories, action_time FROM example"); err != nil {
		log.Fatal(err)
	}
	for _, item := range items {
		log.Printf("country: %s, os: %d, browser: %d, categories: %v, action_time: %s", item.CountryCode, item.OsID, item.BrowserID, item.Categories, item.ActionTime)
	}
}