Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to specify or exclude insert columns #218

Merged
merged 5 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
out
dist
node_modules
webpack
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@
## 0.2.8 (Common, Node.js, Web)

### New features

- (Web only) Allow to modify Keep-Alive setting (previously always disabled).
Keep-Alive setting **is now enabled by default** for the Web version.

```ts
import { createClient } from '@clickhouse/client-web'
const client = createClient({ keep_alive: { enabled: true } })
```

- (Node.js & Web) It is now possible to either specify a list of columns to insert the data into or a list of excluded columns:

```ts
// Generated query: INSERT INTO mytable (message) FORMAT JSONEachRow
await client.insert({
table: 'mytable',
format: 'JSONEachRow',
values: [{ message: 'foo' }],
columns: ['message'],
})

// Generated query: INSERT INTO mytable (* EXCEPT (message)) FORMAT JSONEachRow
await client.insert({
table: 'mytable',
format: 'JSONEachRow',
values: [{ id: 42 }],
columns: { except: ['message'] },
})
```

See also the new examples:

- [Including specific columns or excluding certain ones instead](./examples/insert_exclude_columns.ts)
- [Leveraging this feature](./examples/insert_ephemeral_columns.ts) when working with
[ephemeral columns](https://clickhouse.com/docs/en/sql-reference/statements/create/table#ephemeral)
([#217](https://github.com/ClickHouse/clickhouse-js/issues/217))

## 0.2.7 (Common, Node.js, Web)

### New features
Expand Down
60 changes: 60 additions & 0 deletions examples/insert_ephemeral_columns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { createClient } from '@clickhouse/client' // or '@clickhouse/client-web'

// Ephemeral columns documentation: https://clickhouse.com/docs/en/sql-reference/statements/create/table#ephemeral
// This example is inspired by https://github.com/ClickHouse/clickhouse-js/issues/217
void (async () => {
const tableName = 'insert_ephemeral_columns'
const client = createClient({
clickhouse_settings: {
allow_experimental_object_type: 1, // allows JSON type usage
},
})

await client.command({
query: `
CREATE OR REPLACE TABLE ${tableName}
(
event_type LowCardinality(String) DEFAULT JSONExtractString(message_raw, 'type'),
repo_name LowCardinality(String) DEFAULT JSONExtractString(message_raw, 'repo', 'name'),
message JSON DEFAULT message_raw,
message_raw String EPHEMERAL
)
ENGINE MergeTree()
ORDER BY (event_type, repo_name)
`,
})

await client.insert({
table: tableName,
values: [
{
message_raw: {
type: 'MyEventType',
repo: {
name: 'foo',
},
},
},
{
message_raw: {
type: 'SomeOtherType',
repo: {
name: 'bar',
},
},
},
],
format: 'JSONEachRow',
// The name of the ephemeral column has to be specified here
// to trigger the default values logic for the rest of the columns
columns: ['message_raw'],
})

const rows = await client.query({
query: `SELECT * FROM ${tableName}`,
format: 'JSONCompactEachRowWithNames',
})

console.info(await rows.text())
await client.close()
})()
65 changes: 65 additions & 0 deletions examples/insert_exclude_columns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { createClient } from '@clickhouse/client' // or '@clickhouse/client-web'

void (async () => {
const tableName = 'insert_exclude_columns'
const client = createClient()

await client.command({
query: `
CREATE OR REPLACE TABLE ${tableName}
(id UInt32, message String)
ENGINE MergeTree()
ORDER BY (id)
`,
})

/**
* Explicitly specifying a list of columns to insert the data into
*/
await client.insert({
table: tableName,
values: [{ message: 'foo' }],
format: 'JSONEachRow',
// `id` column value for this row will be zero
columns: ['message'],
})

await client.insert({
table: tableName,
values: [{ id: 42 }],
format: 'JSONEachRow',
// `message` column value for this row will be an empty string
columns: ['id'],
})

/**
* Alternatively, it is possible to exclude certain columns instead
*/
await client.insert({
table: tableName,
values: [{ message: 'bar' }],
format: 'JSONEachRow',
// `id` column value for this row will be zero
columns: {
except: ['id'],
},
})

await client.insert({
table: tableName,
values: [{ id: 144 }],
format: 'JSONEachRow',
// `message` column value for this row will be an empty string
columns: {
except: ['message'],
},
})

const rows = await client.query({
query: `SELECT * FROM ${tableName} ORDER BY id, message DESC`,
format: 'JSONEachRow',
})

console.info(await rows.json())
await client.close()
})()
Loading
Loading