This is a Golang driver for ClickHouse column-oriented database management system
Clone or download
kshvakov Merge pull request #129 from Niev/fix/uuid_read_write_bytes_order
swap order of UUID bytes 0-7 and 8-15 when reading and writing to clickhouse
Latest commit 3414b60 Oct 9, 2018
Permalink
Failed to load latest commit information.
examples custom types converter Aug 30, 2017
lib Merge pull request #129 from Niev/fix/uuid_read_write_bytes_order Oct 9, 2018
.gitignore #58 try codecov.io Aug 20, 2017
.travis.yml Travis CI: Go 1.10/1.11 Oct 9, 2018
CONTRIBUTING.md Use Docker Compose. Sep 8, 2017
LICENSE prototype Jan 11, 2017
Makefile Install package to speed up test. Sep 8, 2017
README.md highlight batch insert as key feature May 19, 2018
array.go rename internal to lib Aug 16, 2017
bootstrap.go Fixing the problem with alter table query execution Sep 10, 2018
clickhouse.go Fix package paths Aug 24, 2018
clickhouse_columnar_test.go write blocks concurrently with columnar writer Aug 23, 2017
clickhouse_custom_types_test.go #64 add missing support of driver.Valuer interface Aug 30, 2017
clickhouse_direct_test.go Fix package paths Aug 24, 2018
clickhouse_exception.go add support Array types for direct interface Aug 17, 2017
clickhouse_naive_test.go update readme Jan 27, 2017
clickhouse_negative_test.go parse enum type Jan 29, 2017
clickhouse_nullable_test.go #133 fix Oct 9, 2018
clickhouse_ping.go #100 PingContext is now supported Apr 18, 2018
clickhouse_profile_info.go add support Array types for direct interface Aug 17, 2017
clickhouse_progress.go remove support for older versions of ClickHouse Aug 29, 2017
clickhouse_read_block.go #74 #86 read/write timeouts Feb 8, 2018
clickhouse_read_meta.go Fixing the problem with alter table query execution Sep 10, 2018
clickhouse_send_query.go #74 #86 read/write timeouts Feb 8, 2018
clickhouse_test.go Fix package paths Aug 24, 2018
clickhouse_write_block.go #74 #86 read/write timeouts Feb 8, 2018
connect.go #74 #86 read/write timeouts Feb 8, 2018
docker-compose.yml Use Docker Compose. Sep 8, 2017
go.test.sh #58 try codecov.io Aug 20, 2017
helpers.go Fixing the problem with panic "sql: Register called twice for driver". Aug 24, 2018
helpers_test.go Added support to pass limit values as bind variables, tests Aug 16, 2018
issues_test.go fix: write nulls to Nullable Enums Nov 7, 2017
result.go update readme Jan 27, 2017
rows.go #100 PingContext is now supported Apr 18, 2018
stmt.go add extra operators when looking for keywords in stmt.bind Oct 5, 2018
value_converter.go Fix package paths Aug 24, 2018
word_matcher.go Added support to pass limit values as bind variables, tests Aug 16, 2018
word_matcher_test.go Added support to pass limit values as bind variables, tests Aug 16, 2018
write_column.go write blocks concurrently with columnar writer Aug 23, 2017

README.md

ClickHouse Build Status Go Report Card codecov

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

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
  • debug - enable debug output (boolean value)

SSL/TLS parameters:

  • secure - establish secure connection (default is false)
  • skip_verify - skip certificate verification (default is true)

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
  • Enum
  • UUID
  • Nullable(T)
  • Array(T) (one-dimensional) godoc

TODO

  • Compression

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