-
Notifications
You must be signed in to change notification settings - Fork 30
/
insert_data_formats_overview.ts
164 lines (156 loc) · 5.03 KB
/
insert_data_formats_overview.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import { createClient } from '@clickhouse/client'
import type { DataFormat } from '@clickhouse/client-common'
import {
type InputJSON,
type InputJSONObjectEachRow,
} from '@clickhouse/client-common'
/**
* An overview of available formats for inserting your data, mainly in different JSON formats.
* For "raw" formats, such as:
* - CSV
* - CSVWithNames
* - CSVWithNamesAndTypes
* - TabSeparated
* - TabSeparatedRaw
* - TabSeparatedWithNames
* - TabSeparatedWithNamesAndTypes
* - CustomSeparated
* - CustomSeparatedWithNames
* - CustomSeparatedWithNamesAndTypes
* - Parquet
* insert method requires a Stream as its input; see the streaming examples:
* - streaming from a CSV file - node/insert_file_stream_csv.ts
* - streaming from a Parquet file - node/insert_file_stream_parquet.ts
*
* If some format is missing from the overview, you could help us by updating this example or submitting an issue.
*
* See also:
* - ClickHouse formats documentation - https://clickhouse.com/docs/en/interfaces/formats
* - SELECT formats overview - select_data_formats_overview.ts
*/
void (async () => {
const tableName = 'insert_data_formats_overview'
const client = createClient()
await prepareTestTable()
// These JSON formats can be streamed as well instead of sending the entire data set at once;
// See this example that streams a file: node/insert_file_stream_ndjson.ts
console.log('#### Streamable JSON formats:\n')
// All of these formats accept various arrays of objects, depending on the format.
await insertJSON('JSONEachRow', [
{ id: 1, name: 'foo', sku: [1, 2, 3] },
{ id: 2, name: 'bar', sku: [4, 5, 6] },
])
await insertJSON('JSONStringsEachRow', [
{ id: '3', name: 'foo', sku: '[1,2,3]' },
{ id: '4', name: 'bar', sku: '[4,5,6]' },
])
await insertJSON('JSONCompactEachRow', [
[5, 'foo', [1, 2, 3]],
[6, 'bar', [4, 5, 6]],
])
await insertJSON('JSONCompactStringsEachRow', [
['7', 'foo', '[1,2,3]'],
['8', 'bar', '[4,5,6]'],
])
await insertJSON('JSONCompactEachRowWithNames', [
['id', 'name', 'sku'],
[9, 'foo', [1, 2, 3]],
[10, 'bar', [4, 5, 6]],
])
await insertJSON('JSONCompactEachRowWithNamesAndTypes', [
['id', 'name', 'sku'],
['UInt32', 'String', 'Array(UInt32)'],
[11, 'foo', [1, 2, 3]],
[12, 'bar', [4, 5, 6]],
])
await insertJSON('JSONCompactStringsEachRowWithNames', [
['id', 'name', 'sku'],
['13', 'foo', '[1,2,3]'],
['14', 'bar', '[4,5,6]'],
])
await insertJSON('JSONCompactStringsEachRowWithNamesAndTypes', [
['id', 'name', 'sku'],
['UInt32', 'String', 'Array(UInt32)'],
['15', 'foo', '[1,2,3]'],
['16', 'bar', '[4,5,6]'],
])
// These are single document JSON formats, which are not streamable
console.log('\n#### Single document JSON formats:\n')
// JSON, JSONCompact, JSONColumnsWithMetadata accept the InputJSON<T> shape.
// For example: https://clickhouse.com/docs/en/interfaces/formats#json
const meta: InputJSON['meta'] = [
{ name: 'id', type: 'UInt32' },
{ name: 'name', type: 'String' },
{ name: 'sku', type: 'Array(UInt32)' },
]
await insertJSON('JSON', {
meta: [], // not required for JSON format input
data: [
{ id: 17, name: 'foo', sku: [1, 2, 3] },
{ id: 18, name: 'bar', sku: [4, 5, 6] },
],
})
await insertJSON('JSONCompact', {
meta,
data: [
[19, 'foo', [1, 2, 3]],
[20, 'bar', [4, 5, 6]],
],
})
await insertJSON('JSONColumnsWithMetadata', {
meta,
data: {
id: [21, 22],
name: ['foo', 'bar'],
sku: [
[1, 2, 3],
[4, 5, 6],
],
},
})
// JSONObjectEachRow accepts Record<string, T> (alias: InputJSONObjectEachRow<T>).
// See https://clickhouse.com/docs/en/interfaces/formats#jsonobjecteachrow
await insertJSON('JSONObjectEachRow', {
row_1: { id: 23, name: 'foo', sku: [1, 2, 3] },
row_2: { id: 24, name: 'bar', sku: [4, 5, 6] },
})
// Print the inserted data - see that the IDs are matching.
await printInsertedData()
await client.close()
// Inserting data in different JSON formats
async function insertJSON<T = unknown>(
format: DataFormat,
values: ReadonlyArray<T> | InputJSON<T> | InputJSONObjectEachRow<T>,
) {
try {
await client.insert({
table: tableName,
format: format,
values,
})
console.log(`Successfully inserted data with format ${format}`)
} catch (err) {
console.error(`Failed to insert data with format ${format}, cause:`, err)
process.exit(1)
}
}
async function prepareTestTable() {
await client.command({
query: `
CREATE OR REPLACE TABLE ${tableName}
(id UInt32, name String, sku Array(UInt32))
ENGINE MergeTree()
ORDER BY (id)
`,
})
}
async function printInsertedData() {
const resultSet = await client.query({
query: `SELECT * FROM ${tableName} ORDER BY id ASC`,
format: 'JSONEachRow',
})
const data = await resultSet.json()
console.log('Inserted data:')
console.dir(data, { depth: null })
}
})()