示例
以下示例使用 flights.csv 文件。
从磁盘读取 CSV 文件,自动推断选项
SELECT * FROM 'flights.csv';
使用带有自定义选项的 read_csv 函数
SELECT *
FROM read_csv('flights.csv',
delim = '|',
header = true,
columns = {
'FlightDate': 'DATE',
'UniqueCarrier': 'VARCHAR',
'OriginCityName': 'VARCHAR',
'DestCityName': 'VARCHAR'
});
从标准输入(stdin)读取 CSV,自动推断选项
cat flights.csv | duckdb -c "SELECT * FROM read_csv('/dev/stdin')"
将 CSV 文件读取到表中
CREATE TABLE ontime (
FlightDate DATE,
UniqueCarrier VARCHAR,
OriginCityName VARCHAR,
DestCityName VARCHAR
);
COPY ontime FROM 'flights.csv';
或者,使用 CREATE TABLE ... AS SELECT 语句,无需手动指定 schema 即可创建表
CREATE TABLE ontime AS
SELECT * FROM 'flights.csv';
我们可以使用 FROM-first 语法来省略 SELECT *。
CREATE TABLE ontime AS
FROM 'flights.csv';
CSV 加载
CSV 加载(即向数据库导入 CSV 文件)是一项非常常见但又出奇复杂的任务。虽然 CSV 表面上看起来很简单,但 CSV 文件中存在许多不一致之处,这使得加载它们成为一项挑战。CSV 文件种类繁多,经常损坏,且没有 schema。CSV 读取器需要应对所有这些不同的情况。
DuckDB CSV 读取器可以通过 CSV 嗅探器(sniffer)分析 CSV 文件,从而自动推断要使用的配置标志。这在大多数情况下都能正常工作,应作为首选尝试。在极少数 CSV 读取器无法识别正确配置的情况下,可以手动配置 CSV 读取器以正确解析 CSV 文件。有关详细信息,请参阅 自动检测页面。
参数
以下是可以传递给 read_csv 函数的参数。在适用且有意义的情况下,这些参数也可以传递给 COPY 语句。
| 名称 | 描述 | 类型 | 默认值 |
|---|---|---|---|
all_varchar |
跳过类型检测,并假设所有列的类型均为 VARCHAR。此选项仅由 read_csv 函数支持。 |
BOOL |
false |
allow_quoted_nulls |
允许将带引号的值转换为 NULL 值 |
BOOL |
true |
auto_detect |
自动检测 CSV 参数. | BOOL |
true |
auto_type_candidates |
嗅探器在检测列类型时使用的候选类型。 VARCHAR 类型始终作为后备选项包含在内。参见 示例。 |
TYPE[] |
默认类型 |
buffer_size |
用于读取文件的缓冲区大小(以字节为单位)。必须足够大以容纳四行,并且会显著影响性能。 | BIGINT |
16 * max_line_size |
columns |
列名和类型(以结构体形式,例如 {'col1': 'INTEGER', 'col2': 'VARCHAR'})。使用此选项将禁用 schema 的自动检测。 |
STRUCT |
(空) |
comment |
用于启动注释的字符。以注释字符开头的行(前面可选地带有空格字符)将被完全忽略;包含注释字符的其他行仅解析到该位置为止。 | VARCHAR |
(空) |
compression |
用于压缩 CSV 文件的方法。默认情况下,这是根据文件扩展名自动检测的(例如 t.csv.gz 将使用 gzip,t.csv 将使用 none)。选项包括 none、gzip、zstd。 |
VARCHAR |
auto |
dateformat |
解析和写入日期时使用的 日期格式。 | VARCHAR |
(空) |
date_format |
dateformat 的别名;仅在 COPY 语句中可用。 |
VARCHAR |
(空) |
decimal_separator |
数字的十进制分隔符。 | VARCHAR |
. |
delim |
用于分隔每一行中各列的分隔符字符,例如 ,、;、\t。分隔符字符最多可达 4 个字节,例如 🦆。sep 的别名。 |
VARCHAR |
, |
delimiter |
delim 的别名;仅在 COPY 语句中可用。 |
VARCHAR |
, |
escape |
用于转义带引号值内的 quote 字符的字符串。 |
VARCHAR |
" |
encoding |
CSV 文件使用的编码。选项包括 utf-8、utf-16、latin-1。在 COPY 语句中不可用(该语句始终使用 utf-8)。 |
VARCHAR |
utf-8 |
文件名 |
将包含该文件的路径添加到每一行中,作为一个名为 filename 的字符串列。根据提供给 read_csv 的路径或 glob 模式,返回的是相对路径或绝对路径,而不仅仅是文件名。自 DuckDB v1.3.0 起,filename 列会自动作为虚拟列添加,保留此选项仅出于兼容性原因。 |
BOOL |
false |
force_not_null |
不将指定列中的值与 NULL 字符串进行匹配。在 NULL 字符串为空的默认情况下,这意味着空值将被读取为零长度字符串而不是 NULL。 |
VARCHAR[] |
[] |
header |
每个文件的第一行包含列名。 | BOOL |
false |
hive_partitioning |
将路径解释为 Hive 分区路径。 | BOOL |
(自动检测) |
ignore_errors |
忽略遇到的任何解析错误。 | BOOL |
false |
max_line_size 或 maximum_line_size。在 COPY 语句中不可用。 |
最大行大小(以字节为单位)。 | BIGINT |
2000000 |
names 或 column_names |
列名(以列表形式)。参见 示例。 | VARCHAR[] |
(空) |
new_line |
换行字符。选项为 '\r'、'\n' 或 '\r\n'。CSV 解析器仅区分单字符和双字符行分隔符。因此,它不区分 '\r' 和 '\n'。 |
VARCHAR |
(空) |
normalize_names |
规范化列名。这会从中删除任何非字母数字字符。保留的 SQL 关键字的列名将以底线字符(_)作为前缀。 |
BOOL |
false |
null_padding |
当某行缺少列时,用 NULL 值填充右侧剩余的列。 |
BOOL |
false |
nullstr 或 null |
表示 NULL 值的字符串。 |
VARCHAR 或 VARCHAR[] |
(空) |
parallel |
使用并行 CSV 读取器。 | BOOL |
true |
quote |
用于引用值的字符。 | VARCHAR |
" |
rejects_scan |
用于存储错误扫描信息的 临时表名称。 | VARCHAR |
reject_scans |
rejects_table |
用于存储错误行信息的 临时表名称。 | VARCHAR |
reject_errors |
rejects_limit |
每个文件中记录在拒绝表中的错误行的上限。设置为 0 表示不应用限制。 |
BIGINT |
0 |
sample_size |
用于 参数自动检测 的样本行数。 | BIGINT |
20480 |
sep |
用于分隔每一行中各列的分隔符字符,例如 ,、;、\t。分隔符字符最多可达 4 个字节,例如 🦆。delim 的别名。 |
VARCHAR |
, |
skip |
每个文件开头要跳过的行数。 | BIGINT |
0 |
store_rejects |
跳过任何带有错误的行,并将它们存储在拒绝表中。 | BOOL |
false |
strict_mode |
强制执行 CSV 读取器的严格级别。设置为 true 时,解析器在遇到任何问题时都会报错。设置为 false 时,解析器将尝试读取结构不正确的文件。请注意,读取结构不正确的文件可能会导致歧义;因此,应谨慎使用此选项。 |
BOOL |
true |
thousands |
用于标识数值中千位分隔符的字符。它必须是单个字符,并且与 decimal_separator 选项不同。 |
VARCHAR |
(空) |
timestampformat |
解析和写入时间戳时使用的 时间戳格式。 | VARCHAR |
(空) |
timestamp_format |
timestampformat 的别名;仅在 COPY 语句中可用。 |
VARCHAR |
(空) |
types 或 dtypes 或 column_types |
列类型,可以是列表(按位置)或结构体(按名称)。参见 示例。 | VARCHAR[] 或 STRUCT |
(空) |
union_by_name |
通过 列名 而不是位置来对齐来自不同文件的列。使用此选项会增加内存消耗。 | BOOL |
false |
提示:DuckDB 的 CSV 读取器支持
UTF-8(默认)、UTF-16和Latin-1编码。对于其他编码,可以使用encodings扩展,或者使用诸如iconv命令行工具 进行转换。iconv -f ISO-8859-2 -t UTF-8 input.csv > input-utf-8.csv
auto_type_candidates 详情
auto_type_candidates 选项允许您指定 CSV 读取器在进行 列数据类型检测 时应考虑的数据类型。使用示例:
SELECT * FROM read_csv('csv_file.csv', auto_type_candidates = ['BIGINT', 'DATE']);
auto_type_candidates 选项的默认值为 ['NULL', 'BOOLEAN', 'BIGINT', 'DOUBLE', 'TIME', 'DATE', 'TIMESTAMP', 'VARCHAR']。
CSV 函数
read_csv 会自动尝试通过 CSV 嗅探器 找出 CSV 读取器的正确配置。它还会自动推断列的类型。如果 CSV 文件有标题行,它将使用标题中的名称来命名列。否则,列将被命名为 column0, column1, column2, ...。使用 flights.csv 文件的示例:
SELECT * FROM read_csv('flights.csv');
| 航班日期 | 唯一承运人 | 出发城市名称 | 目的城市名称 |
|---|---|---|---|
| 1988-01-01 | AA | New York, NY | Los Angeles, CA |
| 1988-01-02 | AA | New York, NY | Los Angeles, CA |
| 1988-01-03 | AA | New York, NY | Los Angeles, CA |
路径可以是相对路径(相对于当前工作目录)或绝对路径。
我们也可以使用 read_csv 来创建持久表:
CREATE TABLE ontime AS
SELECT * FROM read_csv('flights.csv');
DESCRIBE ontime;
| 列名 (column_name) | 列类型 (column_type) | null | key | 默认值 (default) | 额外信息 (extra) |
|---|---|---|---|---|---|
| 航班日期 | DATE | 是 (YES) | NULL | NULL | NULL |
| 唯一承运人 | VARCHAR | 是 (YES) | NULL | NULL | NULL |
| 出发城市名称 | VARCHAR | 是 (YES) | NULL | NULL | NULL |
| 目的城市名称 | VARCHAR | 是 (YES) | NULL | NULL | NULL |
SELECT * FROM read_csv('flights.csv', sample_size = 20_000);
如果我们显式设置 delim / sep、quote、escape 或 header,我们可以跳过对该特定参数的自动检测。
SELECT * FROM read_csv('flights.csv', header = true);
可以通过提供 glob 或文件列表一次读取多个文件。有关更多信息,请参阅多文件部分。
使用 COPY 语句写入
COPY 语句可用于将数据从 CSV 文件加载到表中。此语句的语法与 PostgreSQL 中使用的语法相同。要使用 COPY 语句加载数据,我们必须首先创建一个具有正确 schema 的表(匹配 CSV 文件中列的顺序,并使用适合 CSV 文件中值的类型)。COPY 会自动检测 CSV 的配置选项。
CREATE TABLE ontime (
flightdate DATE,
uniquecarrier VARCHAR,
origincityname VARCHAR,
destcityname VARCHAR
);
COPY ontime FROM 'flights.csv';
SELECT * FROM ontime;
| flightdate | uniquecarrier | origincityname | destcityname |
|---|---|---|---|
| 1988-01-01 | AA | New York, NY | Los Angeles, CA |
| 1988-01-02 | AA | New York, NY | Los Angeles, CA |
| 1988-01-03 | AA | New York, NY | Los Angeles, CA |
如果我们想手动指定 CSV 格式,可以使用 COPY 的配置选项来实现。
CREATE TABLE ontime (flightdate DATE, uniquecarrier VARCHAR, origincityname VARCHAR, destcityname VARCHAR);
COPY ontime FROM 'flights.csv' (DELIMITER '|', HEADER);
SELECT * FROM ontime;
读取有问题的 CSV 文件
DuckDB 支持读取错误的 CSV 文件。有关详细信息,请参阅 读取错误 CSV 文件页面。
顺序保留
CSV 读取器遵循 preserve_insertion_order 配置选项以 保留插入顺序。当为 true(默认值)时,CSV 读取器返回的结果集中的行顺序与从文件中读取的相应行顺序相同。当为 false 时,不保证保留顺序。
写入 CSV 文件
DuckDB 可以使用 COPY ... TO 语句 写入 CSV 文件。