{"id":13526951,"url":"https://github.com/TimonKK/clickhouse","last_synced_at":"2025-04-01T08:30:42.082Z","repository":{"id":40257624,"uuid":"61785763","full_name":"TimonKK/clickhouse","owner":"TimonKK","description":"NodeJS client for ClickHouse","archived":false,"fork":false,"pushed_at":"2024-06-16T15:17:41.000Z","size":189,"stargazers_count":220,"open_issues_count":45,"forks_count":87,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-28T22:39:26.814Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TimonKK.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":"2016-06-23T07:50:27.000Z","updated_at":"2025-03-17T02:11:30.000Z","dependencies_parsed_at":"2024-09-23T18:33:37.642Z","dependency_job_id":"d4be23b6-6f8c-4c83-9cd4-07d670364395","html_url":"https://github.com/TimonKK/clickhouse","commit_stats":{"total_commits":130,"total_committers":34,"mean_commits":3.823529411764706,"dds":0.7538461538461538,"last_synced_commit":"1e873270cc23a9079f1ac35655257d0b2f61ff68"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimonKK%2Fclickhouse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimonKK%2Fclickhouse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimonKK%2Fclickhouse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimonKK%2Fclickhouse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TimonKK","download_url":"https://codeload.github.com/TimonKK/clickhouse/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246607107,"owners_count":20804519,"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":[],"created_at":"2024-08-01T06:01:38.265Z","updated_at":"2025-04-01T08:30:41.699Z","avatar_url":"https://github.com/TimonKK.png","language":"JavaScript","funding_links":[],"categories":["Repository","JavaScript","Language bindings"],"sub_categories":["Parsing","JavaScript/Typescript"],"readme":"# clickhouse\nNodeJS client for [ClickHouse](https://clickhouse.yandex/).\nSend query over HTTP interface.\n\nInstall:\n\n```bash\nnpm i clickhouse\n```\n\nExample:\n\n```javascript\nconst { ClickHouse } = require('clickhouse');\n\nconst clickhouse = new ClickHouse();\n```\nor with all options:\n\n```javascript\nconst clickhouse = new ClickHouse({\n\turl: 'http://localhost',\n\tport: 8123,\n\tdebug: false,\n\tbasicAuth: null,\n\tisUseGzip: false,\n\ttrimQuery: false,\n\tusePost: false,\n\tformat: \"json\", // \"json\" || \"csv\" || \"tsv\"\n\traw: false,\n\tconfig: {\n\t\tsession_id                              : 'session_id if neeed',\n\t\tsession_timeout                         : 60,\n\t\toutput_format_json_quote_64bit_integers : 0,\n\t\tenable_http_compression                 : 0,\n\t\tdatabase                                : 'my_database_name',\n\t},\n\t\n\t// This object merge with request params (see request lib docs)\n\treqParams: {\n\t\t...\n\t}\n});\n```\n\nor change \n\n\tbasicAuth: null\nto\n\n\tbasicAuth: {\n\t\tusername: 'default',\n\t\tpassword: '',\n\t},\n\n\n***\n \nExec query:\n```javascript\nconst queries = [\n\t'DROP TABLE IF EXISTS session_temp',\n\n\t`CREATE TABLE session_temp (\n\t\tdate Date,\n\t\ttime DateTime,\n\t\tmark String,\n\t\tips Array(UInt32),\n\t\tqueries Nested (\n\t\t\tact String,\n\t\t\tid UInt32\n\t\t)\n\t)\n\tENGINE=MergeTree(date, (mark, time), 8192)`,\n\n\t'OPTIMIZE TABLE ukit.loadstat PARTITION 201807 FINAL'\n];\n\nfor(const query of queries) {\n\tconst r = await clickhouse.query(query).toPromise();\n\n\tconsole.log(query, r);\n}\n````\n\n***\n\nExec by callback way:\n```javascript\nclickhouse.query(query).exec(function (err, rows) {\n\t...\n});\n````\n\n***\n\nStream:\n```javascript\nclickhouse.query(`SELECT number FROM system.numbers LIMIT 10`).stream()\n\t.on('data', function() {\n\t\tconst stream = this;\n\n\t\tstream.pause();\n\n\t\tsetTimeout(() =\u003e {\n\t\t\tstream.resume();\n\t\t}, 1000);\n\t})\n\t.on('error', err =\u003e {\n\t\t...\n\t})\n\t.on('end', () =\u003e {\n\t\t...\n\t});\n```\n\nor **async** stream:\n```javascript\n// async iteration\nfor await (const row of clickhouse.query(sql).stream()) {\n\tconsole.log(row);\n}\n```\n\n***\n\nAs promise:\n```javascript\nconst rows = await clickhouse.query(query).toPromise();\n\n// use query with external data\nconst rows = await clickhouse.query('SELECT * AS count FROM temp_table', {\n\texternal: [\n\t\t{\n\t\t\tname: 'temp_table',\n\t\t\tdata: e._.range(0, rowCount).map(i =\u003e `str${i}`)\n\t\t},\n\t]\n}).toPromise();\n```\n\n***\n\nSet session:\n```javascript\nclickhouse.sessionId = '...';\nconst r = await clickhouse.query(\n\t`CREATE TEMPORARY TABLE test_table\n\t(_id String, str String)\n\tENGINE=Memory`\n).toPromise();\n````\n\nIn case your application requires specific sessions to manage specific data then you can send `session_id` with each query.\n\n```javascript\nlet mySessionId = 'some_randome_string';\nconst r = await clickhouse.query(\n\t`CREATE TEMPORARY TABLE test_table\n\t(_id String, str String)\n\tENGINE=Memory`, {}, {sessionId: mySessionId}\n).toPromise();\n```\n\nInsert stream:\n```javascript\nconst ws = clickhouse.insert('INSERT INTO session_temp').stream();\nfor(let i = 0; i \u003c= 1000; i++) {\n\tawait ws.writeRow(\n\t\t[\n\t\t\te._.range(0, 50).map(\n\t\t\t\tj =\u003e `${i}:${i * 2}:${j}`\n\t\t\t).join('-')\n\t\t]\n\t);\n}\n\n//wait stream finish\nconst result = await ws.exec();\n```\n\n***\n\nPipe readable stream to writable stream (across transform):\n```javascript\nconst rs = clickhouse.query(query).stream();\n\nconst tf = new stream.Transform({\n\tobjectMode : true,\n\ttransform  : function (chunk, enc, cb) {\n\t\tcb(null, JSON.stringify(chunk) + '\\n');\n\t}\n});\n\nclickhouse.sessionId = Date.now();\nconst ws = clickhouse.insert('INSERT INTO session_temp2').stream();\n\nconst result = await rs.pipe(tf).pipe(ws).exec();\n```\n***\n\ninsert array of objects:\n```javascript\n\n/*\n\tCREATE TABLE IF NOT EXISTS test_array (\n\t\t\t\tdate Date,\n\t\t\t\tstr String,\n\t\t\t\tarr Array(String),\n\t\t\t\tarr2 Array(Date),\n\t\t\t\tarr3 Array(UInt8),\n\t\t\t\tid1 UUID\n\t\t\t) ENGINE=MergeTree(date, date, 8192)\n*/\n\t\tconst rows = [\n\t\t\t{\n\t\t\t\tdate: '2018-01-01',\n\t\t\t\tstr: 'Something1...',\n\t\t\t\tarr: [],\n\t\t\t\tarr2: ['1985-01-02', '1985-01-03'],\n\t\t\t\tarr3: [1,2,3,4,5],\n\t\t\t\tid1: '102a05cb-8aaf-4f11-a442-20c3558e4384'\n\t\t\t},\n\t\t\t\n\t\t\t{\n\t\t\t\tdate: '2018-02-01',\n\t\t\t\tstr: 'Something2...',\n\t\t\t\tarr: ['5670000000', 'Something3...'],\n\t\t\t\tarr2: ['1985-02-02'],\n\t\t\t\tarr3: [],\n\t\t\t\tid1: 'c2103985-9a1e-4f4a-b288-b292b5209de1'\n\t\t\t}\n\t\t];\n\t\t\n\t\tawait clickhouse.insert(\n\t\t\t`insert into test_array \n\t\t\t(date, str, arr, arr2, \n\t\t\t arr3, id1)`,\n\t\t\trows\n\t\t).toPromise();\n```\n***\n\nParameterized Values:\n```javascript\nconst rows = await clickhouse.query(\n\t'SELECT * AS count FROM temp_table WHERE version = {ver:UInt16}',\n\t{\n\t\tparams: {\n\t\t\tver: 1\n\t\t},\n\t}\n).toPromise();\n```\nFor more information on encoding in the query, see [this section](https://clickhouse.com/docs/en/interfaces/http/#cli-queries-with-parameters) of the ClickHouse documentation.\n\n***\n\n**Run Tests**:\n\n```\nnpm install\nnpm run test\n# or\n# node_modules/.bin/mocha --timeout 60000 --slow 5000 -f \"SPECIFIC TEST NAME\"\n```\n\n***\n\n**Changelogs**:\n* 2020-08-26 (v2.6.0)\n\t- A lot of PRs from community\n* 2020-11-02 (v2.4.1)\n\t- Merge list of PR\n\t- fix test with Base Auth check\n* 2020-11-02 (v2.2.0) ___Backward Incompatible Change___\n    - port from url more important than port from config\n* 2020-04-17 (v2.1.0)\n    - Fix query with totals. For json formats work perfect, but for another - doesn't\n* 2019-02-13\n\t- Add compatibility with user and username options \n* 2019-02-07\n\t- Add TLS/SSL Protocol support\n\t- Add async iteration over SELECT\n\t\n\t\n\t\n**Links**\n* request lib doc https://github.com/request/request#requestoptions-callback\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTimonKK%2Fclickhouse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTimonKK%2Fclickhouse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTimonKK%2Fclickhouse/lists"}