← Files ClickHouseARCHIVED FILE
skills/clickhouse-js-node-coding/reference/insert-columns.md
3.14 KB · Sep 30, 2026 · 22:50 UTC
# Insert into Specific Columns / Other Databases
> **Applies to:** all versions. The `columns` option (both forms) and the
> `database` config field are universally supported.
## Answer checklist
When explaining partial-column inserts:
- Show `columns: ['col_a', 'col_b']` for the allowlist form.
- Also mention the inverse `columns: { except: ['col_to_skip'] }` form so the
user knows both supported shapes.
- Explain that omitted columns receive their server-side defaults
(`DEFAULT`, `MATERIALIZED`, `ALIAS`, nullable/type defaults) and inserts can
still fail or produce surprising zero/empty values if the table definition
has no appropriate defaults.
## Insert into specific columns
Pass `columns: string[]` to limit the `INSERT` to a subset. Omitted columns
get their declared default.
```ts
await client.insert({
table: "events",
columns: ["message"], // the rest of the events table columns get their DEFAULTs
format: "JSONEachRow",
values: [{ message: "foo" }],
});
```
## Insert excluding columns
Use `columns: { except: string[] }` for the inverse. Useful when most columns
should default but you want to name only the few to skip.
```ts
await client.insert({
table: "events",
format: "JSONEachRow",
values: [{ message: "bar" }],
columns: { except: ["id"] },
});
```
## Tables with EPHEMERAL columns
[Ephemeral columns](https://clickhouse.com/docs/en/sql-reference/statements/create/table#ephemeral)
are not stored — they only exist to drive `DEFAULT` expressions of other
columns. To trigger that default logic, **the ephemeral column must be in the
`columns` list**, even though no value will be persisted for it.
```ts
await client.command({
query: `
CREATE OR REPLACE TABLE events
(
id UInt64,
message String DEFAULT message_default,
message_default String EPHEMERAL
)
ENGINE MergeTree
ORDER BY id
`,
});
await client.insert({
table: "events",
format: "JSONEachRow",
values: [
{ id: "42", message_default: "foo" },
{ id: "144", message_default: "bar" },
],
// Including the ephemeral column name triggers the DEFAULT expression
columns: ["id", "message_default"],
});
```
## Insert into a different database
If the client's default `database` is not the target, qualify the table name
with `db.table`:
```ts
const client = createClient({ database: "system" });
await client.command({ query: "CREATE DATABASE IF NOT EXISTS analytics" });
await client.insert({
table: "analytics.events", // fully qualified
format: "JSONEachRow",
values: [{ id: 42, message: "foo" }],
});
```
There is no per-call `database` override on `insert()` / `query()` — qualify
the identifier, or create a second client with the desired `database`.
## Common pitfalls
- **Forgetting the ephemeral column in `columns`.** If you list only the
non-ephemeral columns, the `DEFAULT` expression that depends on the
ephemeral value won't fire and you'll get empty/zero defaults instead.
- **Hoping `client.insert({ database: '…' })` works.** It doesn't — qualify
the `table` instead.
- **Mixing the two `columns` forms.** Use either `string[]` _or_
`{ except: string[] }`, not both.
SHA-256: c83bd73c91cb34c7caee5442e5cb6b867ae039bd330748a6c6be4df5cc60d592