{"id":13695620,"url":"https://github.com/mailru/go-clickhouse","last_synced_at":"2025-05-13T22:03:26.268Z","repository":{"id":37269931,"uuid":"95426286","full_name":"mailru/go-clickhouse","owner":"mailru","description":"Golang SQL database driver for Yandex ClickHouse","archived":false,"fork":false,"pushed_at":"2024-11-23T02:26:57.000Z","size":271,"stargazers_count":431,"open_issues_count":14,"forks_count":89,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-04-28T15:21:39.130Z","etag":null,"topics":["clickhouse","database","go"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mailru.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-26T08:40:23.000Z","updated_at":"2025-03-26T08:19:22.000Z","dependencies_parsed_at":"2024-05-28T15:30:26.992Z","dependency_job_id":"748628fc-f685-4626-aca7-7e2762369b67","html_url":"https://github.com/mailru/go-clickhouse","commit_stats":{"total_commits":165,"total_committers":56,"mean_commits":"2.9464285714285716","dds":0.806060606060606,"last_synced_commit":"ea34956a429960f5aadb66c8a04de3d165e697f2"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailru%2Fgo-clickhouse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailru%2Fgo-clickhouse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailru%2Fgo-clickhouse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailru%2Fgo-clickhouse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mailru","download_url":"https://codeload.github.com/mailru/go-clickhouse/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251336398,"owners_count":21573189,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clickhouse","database","go"],"created_at":"2024-08-02T18:00:31.080Z","updated_at":"2025-04-28T15:21:50.961Z","avatar_url":"https://github.com/mailru.png","language":"Go","funding_links":[],"categories":["Language bindings","Go"],"sub_categories":["Golang"],"readme":"# ClickHouse [![Build Status](https://github.com/mailru/go-clickhouse/actions/workflows/test.yml/badge.svg)](https://github.com/mailru/go-clickhouse/actions/workflows/test.yml/badge.svg) [![Go Report Card](https://goreportcard.com/badge/github.com/mailru/go-clickhouse)](https://goreportcard.com/report/github.com/mailru/go-clickhouse) [![Coverage Status](https://coveralls.io/repos/github/mailru/go-clickhouse/badge.svg?branch=master)](https://coveralls.io/github/mailru/go-clickhouse?branch=master)\n\nYet another Golang SQL database driver for [Yandex ClickHouse](https://clickhouse.yandex/)\n\n## Key features\n\n* Uses official http interface\n* Compatibility with database/sql\n* Compatibility with [dbr](https://github.com/mailru/dbr), [chproxy](https://github.com/Vertamedia/chproxy), [clickhouse-bulk](https://github.com/nikepan/clickhouse-bulk)\n* For native interface check out [clickhouse-go](https://github.com/clickhouse/clickhouse-go)\n\n## DSN\n```\nschema://user:password@host[:port]/database?param1=value1\u0026...\u0026paramN=valueN\n```\n### parameters\n* timeout - is the maximum amount of time a dial will wait for a connect to complete\n* idle_timeout - is the maximum amount of time an idle (keep-alive) connection will remain idle before closing itself.\n* read_timeout - specifies the amount of time to wait for a server's response\n* location - timezone to parse Date and DateTime\n* debug - enables debug logging\n* kill_query - enables killing query on the server side if we have error from transport\n* kill_query_timeout - timeout to kill query (default value is 1 second)\n* other clickhouse options can be specified as well (except default_format)\n\nexample:\n```\nhttp://user:password@host:8123/clicks?read_timeout=10s\u0026write_timeout=20s\n```\n\n## Supported data types\n\n* UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64\n* Float32, Float64\n* Decimal(P, S), Decimal32(S), Decimal64(S), Decimal128(S)\n* String\n* FixedString(N)\n* Date\n* DateTime\n* Enum\n* LowCardinality(T)\n* [Array(T) (one-dimensional)](https://clickhouse.yandex/reference_en.html#Array(T))\n* [Nested(Name1 Type1, Name2 Type2, ...)](https://clickhouse.yandex/docs/en/data_types/nested_data_structures/nested/)\n* IPv4, IPv6\n* Tuple\n* SimpleAggregateFunction\n* Map(K, V)\n\nNotes:\n* 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.\n* type `[]byte` are used as raw string (without quoting)\n* for passing value of type `[]uint8` to driver as array - please use the wrapper `clickhouse.Array`\n* for passing decimal value please use the wrappers `clickhouse.Decimal*`\n* for passing IPv4/IPv6 types use `clickhouse.IP`\n* for passing Tuple types use `clickhouse.Tuple` or structs\n* for passing Map types use `clickhouse.Map`\n\n## Supported request params\n\nClickhouse supports setting\n[query_id](https://clickhouse.yandex/docs/en/interfaces/http/) and\n[quota_key](https://clickhouse.yandex/docs/en/operations/quotas/) for each\nquery. The database driver provides ability to set these parameters as well.\n\nThere are constants `QueryID` and `QuotaKey` for correct setting these params.\n\n`quota_key` could be set as empty string, but `query_id` - does not. Keep in\nmind, that setting same `query_id` could produce exception or replace already\nrunning query depending on current Clickhouse settings. See\n[replace_running_query](https://clickhouse.yandex/docs/en/operations/settings/settings/#replace-running-query)\nfor details.\n\nSee `Example` section for use cases.\n\n## Install\n```\ngo get -u github.com/mailru/go-clickhouse/v2\n```\n\n## Example\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/mailru/go-clickhouse/v2\"\n)\n\nfunc main() {\n\tconnect, err := sql.Open(\"chhttp\", \"http://127.0.0.1:8123/default\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tif err := connect.Ping(); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t_, err = connect.Exec(`\n\t\tCREATE TABLE IF NOT EXISTS example (\n\t\t\tcountry_code FixedString(2),\n\t\t\tos_id        UInt8,\n\t\t\tbrowser_id   UInt8,\n\t\t\tcategories   Array(Int16),\n\t\t\taction_day   Date,\n\t\t\taction_time  DateTime\n\t\t) engine=Memory\n\t`)\n\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\ttx, err := connect.Begin()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tstmt, err := tx.Prepare(`\n\t\tINSERT INTO example (\n\t\t\tcountry_code,\n\t\t\tos_id,\n\t\t\tbrowser_id,\n\t\t\tcategories,\n\t\t\taction_day,\n\t\t\taction_time\n\t\t) VALUES (\n\t\t\t?, ?, ?, ?, ?, ?\n\t\t)`)\n\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfor i := 0; i \u003c 100; i++ {\n\t\tif _, err := stmt.Exec(\n\t\t\t\"RU\",\n\t\t\t10+i,\n\t\t\t100+i,\n\t\t\tclickhouse.Array([]int16{1, 2, 3}),\n\t\t\tclickhouse.Date(time.Now()),\n\t\t\ttime.Now(),\n\t\t); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t}\n\n\tif err := tx.Commit(); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\trows, err := connect.Query(`\n\t\tSELECT\n\t\t\tcountry_code,\n\t\t\tos_id,\n\t\t\tbrowser_id,\n\t\t\tcategories,\n\t\t\taction_day,\n\t\t\taction_time\n\t\tFROM\n\t\t\texample`)\n\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfor rows.Next() {\n\t\tvar (\n\t\t\tcountry               string\n\t\t\tos, browser           uint8\n\t\t\tcategories            []int16\n\t\t\tactionDay, actionTime time.Time\n\t\t)\n\t\tif err := rows.Scan(\n\t\t\t\u0026country,\n\t\t\t\u0026os,\n\t\t\t\u0026browser,\n\t\t\t\u0026categories,\n\t\t\t\u0026actionDay,\n\t\t\t\u0026actionTime,\n\t\t); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tlog.Printf(\"country: %s, os: %d, browser: %d, categories: %v, action_day: %s, action_time: %s\",\n\t\t\tcountry, os, browser, categories, actionDay, actionTime,\n\t\t)\n\t}\n\n\tctx := context.Background()\n\trows, err = connect.QueryContext(context.WithValue(ctx, clickhouse.QueryID, \"dummy-query-id\"), `\n\t\tSELECT\n\t\t\tcountry_code,\n\t\t\tos_id,\n\t\t\tbrowser_id,\n\t\t\tcategories,\n\t\t\taction_day,\n\t\t\taction_time\n\t\tFROM\n\t\t\texample`)\n\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfor rows.Next() {\n\t\tvar (\n\t\t\tcountry               string\n\t\t\tos, browser           uint8\n\t\t\tcategories            []int16\n\t\t\tactionDay, actionTime time.Time\n\t\t)\n\t\tif err := rows.Scan(\n\t\t\t\u0026country,\n\t\t\t\u0026os,\n\t\t\t\u0026browser,\n\t\t\t\u0026categories,\n\t\t\t\u0026actionDay,\n\t\t\t\u0026actionTime,\n\t\t); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tlog.Printf(\"country: %s, os: %d, browser: %d, categories: %v, action_day: %s, action_time: %s\",\n\t\t\tcountry, os, browser, categories, actionDay, actionTime,\n\t\t)\n\t}\n}\n```\n\nUse [dbr](https://github.com/mailru/dbr)\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"time\"\n\n\t_ \"github.com/mailru/go-clickhouse/v2\"\n\t\"github.com/mailru/dbr\"\n)\n\nfunc main() {\n\tconnect, err := dbr.Open(\"chhttp\", \"http://127.0.0.1:8123/default\", nil)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tvar items []struct {\n\t\tCountryCode string    `db:\"country_code\"`\n\t\tOsID        uint8     `db:\"os_id\"`\n\t\tBrowserID   uint8     `db:\"browser_id\"`\n\t\tCategories  []int16   `db:\"categories\"`\n\t\tActionTime  time.Time `db:\"action_time\"`\n\t}\n\tsess := connect.NewSession(nil)\n\tquery := sess.Select(\"country_code\", \"os_id\", \"browser_id\", \"categories\", \"action_time\").From(\"example\")\n\tquery.Where(dbr.Eq(\"country_code\", \"RU\"))\n\tif _, err := query.Load(\u0026items); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfor _, item := range items {\n\t\tlog.Printf(\"country: %s, os: %d, browser: %d, categories: %v, action_time: %s\",\n\t\t\titem.CountryCode, item.OsID, item.BrowserID, item.Categories, item.ActionTime,\n\t\t)\n\t}\n}\n```\nUse with [DataDog trace](https://pkg.go.dev/gopkg.in/DataDog/dd-trace-go.v1/contrib/database/sql)\n```go\npackage main\n\nimport (\n\t\"log\"\n\n\tsqltrace \"gopkg.in/DataDog/dd-trace-go.v1/contrib/database/sql\"\n\n\tclickhouse \"github.com/mailru/go-clickhouse/v2\"\n)\n\nfunc main() {\n\t// The first step is to register the clickhouse driver.\n\tsqltrace.Register(\"chhttp\", \u0026clickhouse.Driver{})\n\n\t// Followed by a call to Open.\n    db, err := sqltrace.Open(\"chhttp\", \"http://127.0.0.1:8123/default\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\trows, err := db.Query(\"SELECT name FROM users WHERE age=?\", 27)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer rows.Close()\n}\n\n```\nTrace context propogation using OTEL SDK\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/propagation\"\n\t\"go.opentelemetry.io/otel/sdk/trace\"\n\toteltrace \"go.opentelemetry.io/otel/trace\"\n\n\t\"database/sql\"\n\n\t_ \"github.com/mailru/go-clickhouse/v2\"\n)\n\nfunc startTracing() (oteltrace.TracerProvider, error) {\n\treturn trace.NewTracerProvider(), nil\n}\n\nfunc main() {\n\t// Open DB connection\n\tconnect, err := sql.Open(\"chhttp\", \"http://127.0.0.1:8123/default\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tctx := context.Background()\n\n\t// Get trace provider\n\ttp, err := startTracing()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// Set MapPropagator\n\totel.SetTextMapPropagator(propagation.TraceContext{})\n\n\tif err := connect.PingContext(ctx); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// start span\n\ttrCtx, span := tp.Tracer(\"test\").Start(ctx, \"app-query\")\n\n\t// execute query with span context\n\trows, err := connect.QueryContext(trCtx, \"SELECT COUNT() FROM (SELECT number FROM system.numbers LIMIT 5)\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tspan.End()\n\tvar count uint64\n\tfor rows.Next() {\n\t\tif err := rows.Scan(\u0026count); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t}\n\tfmt.Printf(\"count: %d\\n\", count)\n}\n\n```\n## Go versions\nOfficially support last 4 golang releases\n\n## Additional clickhouse libraries\n\n\n## Development\nYou can check the effect of changes on CI or run tests locally:\n\n``` bash\nmake init # dep ensure and install\nmake test\n```\n\n_Remember that `make init` will add a few binaries used for testing_\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmailru%2Fgo-clickhouse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmailru%2Fgo-clickhouse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmailru%2Fgo-clickhouse/lists"}