⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
COPY 语句

示例

将 CSV 文件读取到 lineitem 表中,使用自动检测的 CSV 选项

COPY lineitem FROM 'lineitem.csv';

将 CSV 文件读取到 lineitem 表中,使用手动指定的 CSV 选项

COPY lineitem FROM 'lineitem.csv' (DELIMITER '|');

将 Parquet 文件读取到 lineitem 表中

COPY lineitem FROM 'lineitem.pq' (FORMAT parquet);

将 JSON 文件读取到 lineitem 表中,使用自动检测选项

COPY lineitem FROM 'lineitem.json' (FORMAT json, AUTO_DETECT true);

将 CSV 文件读取到 lineitem 表中,使用双引号

COPY lineitem FROM "lineitem.csv";

将 CSV 文件读取到 lineitem 表中,省略引号

COPY lineitem FROM lineitem.csv;

将表写入 CSV 文件

COPY lineitem TO 'lineitem.csv' (FORMAT csv, DELIMITER '|', HEADER);

将表写入 CSV 文件,使用双引号

COPY lineitem TO "lineitem.csv";

将表写入 CSV 文件,省略引号

COPY lineitem TO lineitem.csv;

将查询结果写入 Parquet 文件

COPY (SELECT l_orderkey, l_partkey FROM lineitem) TO 'lineitem.parquet' (COMPRESSION zstd);

将数据库 db1 的全部内容复制到数据库 db2

COPY FROM DATABASE db1 TO db2;

仅复制模式(目录元素)但不复制任何数据

COPY FROM DATABASE db1 TO db2 (SCHEMA);

概览

COPY 在 DuckDB 和外部文件之间移动数据。COPY ... FROM 将数据从外部文件导入到 DuckDB。COPY ... TO 将数据从 DuckDB 写入外部文件。COPY 命令可用于 CSVPARQUETJSON 文件。

COPY ... FROM

COPY ... FROM 将数据从外部文件导入到现有表中。数据将追加到表中已有的数据。文件中的列数必须与表 table_name 中的列数匹配,并且列内容必须可转换为表的列类型。如果无法转换,将抛出错误。

如果指定了列列表,COPY 将仅复制文件中指定列的数据。如果表中有任何列未包含在列列表中,COPY ... FROM 将为这些列插入默认值。

将不带标题的逗号分隔文件 test.csv 的内容复制到表 test

COPY test FROM 'test.csv';

将带标题的逗号分隔文件的内容复制到 category 表中

COPY category FROM 'categories.csv' (HEADER);

lineitem.tbl 的内容复制到 lineitem 表中,其中内容由竖线字符 (|) 分隔

COPY lineitem FROM 'lineitem.tbl' (DELIMITER '|');

lineitem.tbl 的内容复制到 lineitem 表中,其中分隔符、引号字符和标题的存在都自动检测

COPY lineitem FROM 'lineitem.tbl' (AUTO_DETECT true);

将逗号分隔文件 names.csv 的内容读取到 category 表的 name 列中。该表的任何其他列都填充其默认值。

COPY category(name) FROM 'names.csv';

将 Parquet 文件 lineitem.parquet 的内容读取到 lineitem 表中

COPY lineitem FROM 'lineitem.parquet' (FORMAT parquet);

将以换行符分隔的 JSON 文件 lineitem.ndjson 的内容读取到 lineitem 表中

COPY lineitem FROM 'lineitem.ndjson' (FORMAT json);

将 JSON 文件 lineitem.json 的内容读取到 lineitem 表中

COPY lineitem FROM 'lineitem.json' (FORMAT json, ARRAY true);

语法

为确保与 PostgreSQL 兼容,DuckDB 接受不完全符合此处所示铁路图的 COPY ... FROM 语句。例如,以下是一个有效语句:

COPY tbl FROM 'tbl.csv' WITH DELIMITER '|' CSV HEADER;

COPY ... TO

COPY ... TO 将数据从 DuckDB 导出到外部 CSV 或 Parquet 文件。它与 COPY ... FROM 大致有相同的选项集,但在 COPY ... TO 的情况下,这些选项指定了文件应如何写入磁盘。通过使用类似选项集的 COPY ... FROM,任何由 COPY ... TO 创建的文件都可以被复制回数据库。

COPY ... TO 函数可以指定表名或查询来调用。当指定表名时,整个表的内容将被写入生成的文件。当指定查询时,查询将被执行,查询结果将写入生成的文件。

lineitem 表的内容复制到带有标题的 CSV 文件中

COPY lineitem TO 'lineitem.csv';

lineitem 表的内容复制到文件 lineitem.tbl 中,其中列由竖线字符 (|) 分隔,并包含标题行

COPY lineitem TO 'lineitem.tbl' (DELIMITER '|');

使用制表符分隔符创建不带标题的 TSV 文件

COPY lineitem TO 'lineitem.tsv' (DELIMITER '\t', HEADER false);

lineitem 表的 l_orderkey 列复制到文件 orderkey.tbl

COPY lineitem(l_orderkey) TO 'orderkey.tbl' (DELIMITER '|');

将查询结果复制到文件 query.csv 中,包括带有列名称的标题

COPY (SELECT 42 AS a, 'hello' AS b) TO 'query.csv' (DELIMITER ',');

将查询结果复制到 Parquet 文件 query.parquet

COPY (SELECT 42 AS a, 'hello' AS b) TO 'query.parquet' (FORMAT parquet);

将查询结果复制到以换行符分隔的 JSON 文件 query.ndjson

COPY (SELECT 42 AS a, 'hello' AS b) TO 'query.ndjson' (FORMAT json);

将查询结果复制到 JSON 文件 query.json

COPY (SELECT 42 AS a, 'hello' AS b) TO 'query.json' (FORMAT json, ARRAY true);

返回作为 COPY 语句一部分写入的文件及其列统计信息

COPY (SELECT l_orderkey, l_comment FROM lineitem) TO 'lineitem_part.parquet' (RETURN_STATS);
文件名 count(计数) file_size_bytes(文件大小字节) footer_size_bytes(页脚大小字节) column_statistics(列统计信息) partition_keys(分区键)
lineitem_part.parquet 600572 8579141 1445 {'"l_comment"'={column_size_bytes=7642227, max=zzle. slyly, min=' Tiresias above the blit', null_count=0}, '"l_orderkey"'={column_size_bytes=935457, max=600000, min=1, null_count=0}} NULL(空)

注意:对于嵌套列(例如,结构体),列统计信息为每个部分定义。例如,如果我们有一个列 name STRUCT(field1 INTEGER, field2 INTEGER),则列统计信息将包含 name.field1name.field2 的统计信息。

COPY ... TO 选项

可以作为复制操作的一部分提供零个或多个复制选项。WITH 指定符是可选的,但如果指定了任何选项,则括号是必需的。参数值可以带或不带单引号。

任何布尔选项都可以通过多种方式启用或禁用。您可以写入 trueON1 来启用选项,写入 falseOFF0 来禁用选项。BOOLEAN 值也可以省略,例如,仅传递 (HEADER),在这种情况下假定为 true

除少数例外,以下选项适用于所有使用 COPY 写入的格式。

名称 描述 类型 默认值
FORMAT(格式) 指定要使用的复制函数。默认值从文件扩展名中选择(例如,.parquet 导致写入/读取 Parquet 文件)。如果文件扩展名未知,则选择 CSV。原版 DuckDB 提供 CSVPARQUETJSON,但可以通过扩展添加额外的复制函数。 VARCHAR auto(自动)
USE_TMP_FILE(使用临时文件) 如果原始文件存在,是否先写入临时文件 (target.csv.tmp)。这可以防止在写入被取消的情况下用损坏的文件覆盖现有文件。 BOOL auto(自动)
OVERWRITE_OR_IGNORE(覆盖或忽略) 如果文件已存在,是否允许覆盖文件。仅与 PARTITION_BY 一起使用时生效。 BOOL false(否)
OVERWRITE(覆盖) 当为 true 时,目标目录中的所有现有文件都将被删除(远程文件系统不支持)。仅与 PARTITION_BY 一起使用时生效。 BOOL false(否)
APPEND(追加) 当为 true 时,如果生成的的文件名模式已存在,则会重新生成路径以确保不覆盖现有文件。仅与 PARTITION_BY 一起使用时生效。 BOOL false(否)
FILENAME_PATTERN(文件名模式) 设置文件名的模式,可选地包含 {uuid} / {uuidv4}{uuidv7} 以填充生成的 UUID(分别为 v4 或 v7),以及 {i},该值将被递增索引替换。仅与 PARTITION_BY 一起使用时生效。 VARCHAR auto(自动)
FILE_EXTENSION(文件扩展名) 设置应分配给生成文件(或多个文件)的文件扩展名。 VARCHAR auto(自动)
PER_THREAD_OUTPUT(按线程输出) 当为 true 时,COPY 命令为每个线程生成一个文件,而不是总共一个文件。这允许更快的并行写入。 BOOL false(否)
FILE_SIZE_BYTES(文件大小字节) 如果设置了此参数,COPY 进程将创建一个目录,其中包含导出的文件。如果文件超过设定的限制(以字节为单位指定,如 1000 或以人类可读格式指定,如 1k),进程将在目录中创建一个新文件。此参数与 PER_THREAD_OUTPUT 结合使用。请注意,大小用作近似值,文件偶尔可能会略微超过限制。 VARCHARBIGINT (空)
PARTITION_BY(分区依据) 要使用 Hive 分区方案进行分区的列,请参阅分区写入部分 VARCHAR[] (空)
PRESERVE_ORDER(保留顺序) 在复制操作期间是否保留顺序。默认为 preserve_insertion_order 配置选项的值。 BOOL (*)
RETURN_FILES(返回文件) 是否在查询结果中包含创建的文件路径(作为 files VARCHAR[] 列)。 BOOL false(否)
RETURN_STATS(返回统计信息) 是否返回作为 COPY 语句一部分写入的文件及其列统计信息。 BOOL false(否)
WRITE_PARTITION_COLUMNS(写入分区列) 是否将分区列写入文件。仅与 PARTITION_BY 一起使用时生效。 BOOL false(否)

语法

为确保与 PostgreSQL 兼容,DuckDB 接受不完全符合此处所示铁路图的 COPY ... TO 语句。例如,以下是一个有效语句:

COPY (SELECT 42 AS x, 84 AS y) TO 'out.csv' WITH DELIMITER '|' CSV HEADER;

COPY FROM DATABASE ... TO

COPY FROM DATABASE ... TO 语句将一个已附加数据库的全部内容复制到另一个已附加数据库。这包括模式,例如约束、索引、序列、宏和数据本身。

ATTACH 'db1.db' AS db1;
CREATE TABLE db1.tbl AS SELECT 42 AS x, 3 AS y;
CREATE MACRO db1.two_x_plus_y(x, y) AS 2 * x + y;

ATTACH 'db2.db' AS db2;
COPY FROM DATABASE db1 TO db2;
SELECT db2.two_x_plus_y(x, y) AS z FROM db2.tbl;
z
87

仅复制 db1 的**模式**到 db2 但省略复制数据,请在语句中添加 SCHEMA

COPY FROM DATABASE db1 TO db2 (SCHEMA);

语法

格式特定选项

CSV 选项

以下选项适用于写入 CSV 文件时。

名称 描述 类型 默认值
COMPRESSION(压缩) 文件的压缩类型。默认情况下,将从文件扩展名自动检测(例如,file.csv.gz 将使用 gzipfile.csv.zst 将使用 zstdfile.csv 将使用 none)。选项包括 nonegzipzstd VARCHAR auto(自动)
DATEFORMAT(日期格式) 指定写入日期时使用的日期格式。请参阅日期格式 VARCHAR (空)
DELIMSEP(分隔符) 写入以分隔每行中列的字符。 VARCHAR ,
ESCAPE(转义符) 在与 quote 值匹配的字符之前应出现的字符。 VARCHAR "
FORCE_QUOTE(强制引用) 始终添加引号的列列表,即使不需要。 VARCHAR[] []
HEADER(标题) 是否为 CSV 文件写入标题。 BOOL true(是)
NULLSTR(空字符串) 表示 NULL 值时写入的字符串。 VARCHAR (空)
PREFIX(前缀) 以指定字符串为 CSV 文件添加前缀。此选项必须与 SUFFIX 结合使用,并要求 HEADER 设置为 false VARCHAR (空)
SUFFIX(后缀) 将指定字符串作为后缀添加到 CSV 文件。此选项必须与 PREFIX 结合使用,并要求 HEADER 设置为 false VARCHAR (空)
QUOTE(引号) 当数据值被引用时使用的引用字符。 VARCHAR "
TIMESTAMPFORMAT(时间戳格式) 指定写入时间戳时使用的日期格式。请参阅日期格式 VARCHAR (空)

Parquet 选项

以下选项适用于写入 Parquet 文件时。

名称 描述 类型 默认值
COMPRESSION(压缩) 要使用的压缩格式(uncompressedsnappygzipzstdbrotlilz4lz4_raw)。 VARCHAR snappy
COMPRESSION_LEVEL(压缩级别) 压缩级别,设置在 1(最低压缩,最快)到 22(最高压缩,最慢)之间。仅支持 zstd 压缩。 BIGINT 3
FIELD_IDS(字段 ID) 每个列的 field_id。传递 auto 以尝试自动推断。 STRUCT (空)
ROW_GROUP_SIZE_BYTES(行组大小字节) 每个行组的目标大小。您可以传递人类可读的字符串,例如 2MB,或者一个整数,即字节数。此选项仅在您执行了 SET preserve_insertion_order = false; 时使用,否则将被忽略。 BIGINT row_group_size * 1024
ROW_GROUP_SIZE(行组大小) 每个行组的目标大小,即行数。 BIGINT 122880
ROW_GROUPS_PER_FILE(每个文件行组数) 如果当前文件具有指定数量的行组,则创建新的 Parquet 文件。如果存在多个活动线程,文件中的行组数可能会略微超过指定的行组数,以限制锁定量——类似于 FILE_SIZE_BYTES 的行为。但是,如果设置了 per_thread_output,则只有一个线程写入每个文件,并且其行为再次变得精确。 BIGINT (空)
PARQUET_VERSION(Parquet 版本) 要使用的 parquet 版本(V1V2)。 VARCHAR V1

FIELD_IDS 的一些示例如下。

自动分配 field_ids

COPY
    (SELECT 128 AS i)
    TO 'my.parquet'
    (FIELD_IDS 'auto');

将列 ifield_id 设置为 42

COPY
    (SELECT 128 AS i)
    TO 'my.parquet'
    (FIELD_IDS {i: 42});

将列 ifield_id 设置为 42,将列 jfield_id 设置为 43

COPY
    (SELECT 128 AS i, 256 AS j)
    TO 'my.parquet'
    (FIELD_IDS {i: 42, j: 43});

将列 my_structfield_id 设置为 43,并将列 i(嵌套在 my_struct 中)的 field_id 设置为 43

COPY
    (SELECT {i: 128} AS my_struct)
    TO 'my.parquet'
    (FIELD_IDS {my_struct: {__duckdb_field_id: 42, i: 43}});

将列 my_listfield_id 设置为 42,并将列 element(列表子项的默认名称)的 field_id 设置为 43

COPY
    (SELECT [128, 256] AS my_list)
    TO 'my.parquet'
    (FIELD_IDS {my_list: {__duckdb_field_id: 42, element: 43}});

将列 my_mapfield_id 设置为 42,并将列 keyvalue(映射子项的默认名称)的 field_id 分别设置为 43 和 44

COPY
    (SELECT MAP {'key1' : 128, 'key2': 256} my_map)
    TO 'my.parquet'
    (FIELD_IDS {my_map: {__duckdb_field_id: 42, key: 43, value: 44}});

JSON 选项

以下选项适用于写入 JSON 文件时。

名称 描述 类型 默认值
ARRAY(数组) 是否写入 JSON 数组。如果为 true,则写入记录的 JSON 数组;如果为 false,则写入以换行符分隔的 JSON BOOL false(否)
COMPRESSION(压缩) 文件的压缩类型。默认情况下,将从文件扩展名自动检测(例如,file.json.gz 将使用 gzipfile.json.zst 将使用 zstdfile.json 将使用 none)。选项包括 nonegzipzstd VARCHAR auto(自动)
DATEFORMAT(日期格式) 指定写入日期时使用的日期格式。请参阅日期格式 VARCHAR (空)
TIMESTAMPFORMAT(时间戳格式) 指定写入时间戳时使用的日期格式。请参阅日期格式 VARCHAR (空)

限制

COPY 不支持表之间的数据复制。要在表之间复制,请使用 INSERT 语句

INSERT INTO tbl2
    FROM tbl1;