Golang SQL database driver for Yandex ClickHouse
Clone or download
Latest commit 87c3659 Jan 11, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.gitignore Go dep, local tests, minor refactoring (#52) Nov 18, 2018
.travis.yml Go dep, local tests, minor refactoring (#52) Nov 18, 2018
Gopkg.toml Go dep, local tests, minor refactoring (#52) Nov 18, 2018
LICENSE Introduced database/sql driver for clickhouse Jun 26, 2017
Makefile Go dep, local tests, minor refactoring (#52) Nov 18, 2018
README.md Better Decimal support Jan 12, 2019
clickhouse.go Introduced database/sql driver for clickhouse Jun 26, 2017
clickhouse_test.go Better Decimal support Jan 12, 2019
config.go Go dep, local tests, minor refactoring (#52) Nov 18, 2018
config_test.go - sort imports (goimport) Feb 24, 2018
conn.go Close unused response bodies to avoid leaks. (#58) Nov 28, 2018
conn_go18.go Streaming query Sep 11, 2018
conn_go18_test.go Better Decimal support Jan 12, 2019
conn_go19_test.go ConvertValue tests added (#33) Aug 16, 2018
conn_test.go Better Decimal support Jan 12, 2019
dataparser.go Better Decimal support Jan 12, 2019
dataparser_test.go Better Decimal support Jan 12, 2019
encoder.go Enable decoding nested structures (#47) Jan 10, 2019
encoder_test.go Enable decoding nested structures (#47) Jan 10, 2019
errors.go add space to the start of the error regexp Jul 24, 2018
helpers.go Enable decoding nested structures (#47) Jan 10, 2019
interpolate.go Encoded improvments for better Arrays support #35 Aug 22, 2018
interpolate_test.go - sort imports (goimport) Feb 24, 2018
result.go Introduced database/sql driver for clickhouse Jun 26, 2017
rows.go Add LazyQuotes for groupArray(String) (#55) Jan 12, 2019
rows_test.go Add LazyQuotes for groupArray(String) (#55) Jan 12, 2019
stmt.go Fix for multiline insert queries (#54) Nov 26, 2018
stmt_go18.go Introduced database/sql driver for clickhouse Jun 26, 2017
stmt_go18_test.go Fix using 'sleep' function in tests Sep 17, 2018
stmt_test.go Fix for multiline insert queries (#54) Nov 26, 2018
tokenizer.go Enable decoding nested structures (#47) Jan 10, 2019
tokenizer_test.go Enable decoding nested structures (#47) Jan 10, 2019
typeparser.go Enable decoding nested structures (#47) Jan 10, 2019
typeparser_test.go Better Decimal support Jan 12, 2019
types.go Better Decimal support Jan 12, 2019
types_test.go Better Decimal support Jan 12, 2019
value_converter.go ConvertValue tests added (#33) Aug 16, 2018
value_converter_test.go ConvertValue tests added (#33) Aug 16, 2018

README.md

ClickHouse Build Status Go Report Card Coverage Status

Yet another Golang SQL database driver for Yandex ClickHouse

Key features

  • Uses official http interface
  • Compatibility with dbr

DSN

schema://user:password@host[:port]/database?param1=value1&...&paramN=valueN

parameters

  • timeout - is the maximum amount of time a dial will wait for a connect to complete
  • idle_timeout - is the maximum amount of time an idle (keep-alive) connection will remain idle before closing itself.
  • read_timeout - specifies the amount of time to wait for a server's response
  • location - timezone to parse Date and DateTime
  • debug - enables debug logging
  • other clickhouse options can be specified as well (except default_format)

example:

http://user:password@host:8123/clicks?read_timeout=10&write_timeout=20

Supported data types

Notes: database/sql does not allow to use big uint64 values. It is recommended use type UInt64 which is provided by driver for such kind of values. type []byte are used as raw string (without quoting) for passing value of type []uint8 to driver as array - please use the wrapper clickhouse.Array for passing decimal value please use the wrappers clickhouse.Decimal*

Install

go get -u github.com/mailru/go-clickhouse

Example

package main

import (
	"database/sql"
	"log"
	"time"

	"github.com/mailru/go-clickhouse"
)

func main() {
	connect, err := sql.Open("clickhouse", "http://127.0.0.1:8123/default")
	if err != nil {
		log.Fatal(err)
	}
	if err := connect.Ping(); err != nil {
		log.Fatal(err)
	}

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

	tx, err := connect.Begin()
	if err != nil {
		log.Fatal(err)
	}
	stmt, err := tx.Prepare(`
		INSERT INTO example (
			country_code,
			os_id,
			browser_id,
			categories,
			action_day,
			action_time
		) VALUES (
			?, ?, ?, ?, ?, ?
		)`)

	if err != nil {
		log.Fatal(err)
	}

	for i := 0; i < 100; i++ {
		if _, err := stmt.Exec(
			"RU",
			10+i,
			100+i,
			clickhouse.Array([]int16{1, 2, 3}),
			clickhouse.Date(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)
	}

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

Use dbr

package main

import (
	"log"
	"time"

	_ "github.com/mailru/go-clickhouse"
	"github.com/mailru/dbr"
)

func main() {
	connect, err := dbr.Open("clickhouse", "http://127.0.0.1:8123/default", nil)
	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"`
	}
	sess := connect.NewSession(nil)
	query := sess.Select("country_code", "os_id", "browser_id", "categories", "action_time").From("example")
	query.Where(dbr.Eq("country_code", "RU"))
	if _, err := query.Load(&items); 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,
		)
	}
}

Go versions

Officially support last 3 golang releases

Development

You can check the effect of changes on Travis CI or run tests locally:

make init # dep ensure and install
make test

Remember that make init will add a few binaries used for testing (like golint and it's dependencies) into your GOPATH