⌘+k ctrl+k
1.1.3 (stable)
Search Shortcut cmd + k | ctrl + k
COPY Statement

Examples

将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);

Overview

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);

Syntax

COPY ... TO

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

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 ... TO 选项

零个或多个复制选项可以作为复制操作的一部分提供。WITH 说明符是可选的,但如果指定了任何选项,则需要括号。参数值可以传递,无论是否用单引号包裹。

任何布尔类型的选项都可以通过多种方式启用或禁用。你可以写trueON1来启用选项,写falseOFF0来禁用它。BOOLEAN值也可以省略,例如只传递(HEADER),在这种情况下,默认为true

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

Name Description Type Default
FORMAT 指定要使用的复制函数。默认值根据文件扩展名选择(例如,.parquet 会导致写入/读取 Parquet 文件)。如果文件扩展名未知,则选择 CSV。Vanilla DuckDB 提供 CSVPARQUETJSON,但可以通过 extensions 添加其他复制函数。 VARCHAR auto
USE_TMP_FILE 如果原始文件存在,是否首先写入临时文件(target.csv.tmp)。这可以防止在写入被取消时用损坏的文件覆盖现有文件。 BOOL auto
OVERWRITE_OR_IGNORE 是否允许覆盖已存在的文件。仅在与partition_by一起使用时有效。 BOOL false
OVERWRITE 当设置时,目标目录内的所有现有文件将被删除(远程文件系统不支持)。仅在与partition_by一起使用时有效。 BOOL false
APPEND 当设置时,如果生成的文件名模式已经存在,路径将被重新生成,以确保不会覆盖现有文件。仅在与partition_by一起使用时有效。 BOOL false
FILENAME_PATTERN 设置用于文件名的模式,可以选择包含{uuid}以填充生成的UUID或{id}以替换为递增的索引。仅在与partition_by一起使用时有效。 VARCHAR auto
FILE_EXTENSION 设置应分配给生成文件的文件扩展名。 VARCHAR auto
PER_THREAD_OUTPUT 为每个线程生成一个文件,而不是总共生成一个文件。这样可以实现更快的并行写入。 BOOL false
FILE_SIZE_BYTES 如果设置了此参数,COPY 过程将创建一个目录,该目录将包含导出的文件。如果文件超过设置的限制(以字节为单位指定,如 1000 或以人类可读的格式指定,如 1k),该过程将在目录中创建一个新文件。此参数与 PER_THREAD_OUTPUT 结合使用。请注意,大小用作近似值,文件有时可能会略微超过限制。 VARCHARBIGINT (空)
PARTITION_BY 使用Hive分区方案进行分区的列,请参阅分区写入部分 VARCHAR[] (空)
RETURN_FILES 是否在查询结果中包含生成的文件路径(作为Files VARCHAR[]列)。 BOOL false
WRITE_PARTITION_COLUMNS 是否将分区列写入文件。仅在与partition_by一起使用时有效。 BOOL false

Syntax

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);

Syntax

格式特定选项

CSV 选项

以下选项在编写CSV文件时适用。

Name Description Type Default
COMPRESSION 文件的压缩类型。默认情况下,这将根据文件扩展名自动检测(例如,file.csv.gz 将使用 gzipfile.csv.zst 将使用 zstd,而 file.csv 将使用 none)。选项包括 nonegzipzstd VARCHAR auto
DATEFORMAT 指定写入日期时使用的日期格式。参见 日期格式 VARCHAR (空)
DELIMSEP 用于分隔每行中各列的字符。 VARCHAR ,
ESCAPE 应该出现在与quote值匹配的字符之前的字符。 VARCHAR "
FORCE_QUOTE 始终添加引号的列列表,即使不需要。 VARCHAR[] []
HEADER 是否要为CSV文件写入标题。 BOOL true
NULLSTR 用于表示NULL值的字符串。 VARCHAR (空)
QUOTE 当数据值被引用时使用的引用字符。 VARCHAR "
TIMESTAMPFORMAT 指定写入时间戳时使用的日期格式。参见 日期格式 VARCHAR (空)

Parquet 选项

以下选项在编写Parquet文件时适用。

Name Description Type Default
COMPRESSION 使用的压缩格式(uncompressed, snappy, gzipzstd)。 VARCHAR snappy
COMPRESSION_LEVEL 压缩级别,设置在1(最低压缩,最快)和22(最高压缩,最慢)之间。仅支持zstd压缩。 BIGINT 3
FIELD_IDS 每列的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 (空)

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,列 j 设置为 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 内)设置为 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(列表子元素的默认名称)设置为 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(map 子元素的默认名称)分别设置为 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文件时。

Name Description Type Default
ARRAY 是否写入JSON数组。如果为true,则写入记录的JSON数组,如果为false,则写入换行分隔的JSON BOOL false
COMPRESSION 文件的压缩类型。默认情况下,这将根据文件扩展名自动检测(例如,file.json.gz 将使用 gzipfile.json.zst 将使用 zstd,而 file.json 将使用 none)。选项包括 nonegzipzstd VARCHAR auto
DATEFORMAT Specifies the date format to use when writing dates. See Date Format VARCHAR (empty)
TIMESTAMPFORMAT 指定写入时间戳时使用的日期格式。参见 日期格式 VARCHAR (空)

Limitations

COPY 不支持在表之间进行复制。要在表之间复制数据,请使用 INSERT statement

INSERT INTO tbl2
    FROM tbl1;