跪拜 Guibai
← All articles
Database

The Backslash That Decides Where Your CSV Lands: ksql's \copy vs. COPY

By 一只牛博 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

The `\copy` vs `COPY` distinction is a concrete workflow difference that eliminates a recurring friction point: needing elevated database privileges or server access just to get a CSV file onto a developer's laptop. For teams running KingbaseES (a PostgreSQL derivative common in Chinese enterprises), knowing that the backslash moves execution to the client side turns a DBA-gated operation into a self-service one-liner.

Summary

Exporting query results to CSV for non-technical teams often means wrestling with server-side file permissions in MySQL. KingbaseES's ksql client sidesteps this entirely with `\copy`, a meta-command that executes locally. The file lands on the developer's machine, not the database server, and any ordinary database user can run it. The command supports full-table dumps, filtered SELECT exports with custom columns, and CSV imports that map specific file columns to table columns while letting defaults handle the rest.

The critical distinction is execution context. `COPY` (no backslash) is a server-side SQL command requiring superuser or `sys_write_server_files` role. `\copy` (with backslash) runs in the ksql process on the client machine. The same table, same path, same options produce radically different results depending on that single character. The error message is explicit: anyone can use `\copy`.

For daily workflows — handing a CSV to operations, ingesting a batch file from a partner — the pattern `\copy (SELECT ...) TO 'file' WITH (FORMAT CSV, HEADER true)` replaces temporary tables and server round-trips. An encoding option handles Windows GBK files without pre-conversion.

Takeaways
`\copy` is a ksql client meta-command; the file is written on the machine running ksql, not the database server.
`COPY` (no backslash) is a server-side SQL command requiring superuser or `sys_write_server_files` role.
`\copy (SELECT ...) TO 'file' WITH (FORMAT CSV, HEADER true)` exports filtered columns and rows directly, no temporary tables needed.
During import, a parenthesized column list maps CSV columns to specific table columns; omitted columns use their defaults.
`HEADER true` outputs column names on export and skips the header row on import.
Windows GBK-encoded CSVs can be handled inline with `ENCODING 'GBK'` in the `WITH` clause.
`\copy` must be written on a single line; it cannot wrap like standard SQL.
Conclusions

The `\copy` / `COPY` split is a clean separation of concerns: client-side for ad-hoc data tasks by developers, server-side for DBA-managed bulk operations. The backslash encodes who runs the command and whose filesystem permissions matter.

MySQL's `SELECT INTO OUTFILE` and `LOAD DATA INFILE` default to server-side execution, making the `LOCAL` keyword an opt-in client-side escape hatch. KingbaseES inverts this: `\copy` is client-side by default, and server-side `COPY` is the restricted variant. The ergonomics favor the common case — a developer on their own machine.

Encoding handling is a small detail that prevents a large headache in Chinese enterprise environments, where Excel-generated GBK CSVs are routine. Baking `ENCODING` into the `WITH` clause avoids a separate transcoding step that non-technical staff won't perform.

Concepts & terms
ksql
The command-line client for KingbaseES, analogous to psql for PostgreSQL. It provides meta-commands (prefixed with backslash) that execute client-side.
\copy (ksql meta-command)
A client-side command executed by the ksql process on the local machine. Reads from or writes to the local filesystem using the OS user's permissions, requiring no database superuser privileges.
COPY (SQL command)
A server-side SQL command executed by the database server. File paths refer to the server's filesystem, and execution requires superuser or the `sys_write_server_files` role in KingbaseES.
search_path
A PostgreSQL/KingbaseES setting that determines which schemas are searched when an unqualified table name is used. `\copy` relies on it to resolve short table names within the current session.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗