示例
以下示例使用 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
优先语法来省略 SELECT *
。
CREATE TABLE ontime AS
FROM 'flights.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 |
sniffer 在检测列类型时使用的类型。 VARCHAR 类型始终作为备用选项包含在内。请参阅示例。 |
TYPE[] |
默认类型 |
buffer_size |
用于读取文件的缓冲区大小,以字节为单位。必须足够大以容纳四行,并且会显著影响性能。 | BIGINT |
16 * max_line_size |
columns |
列名和类型,作为结构体(例如,{'col1': 'INTEGER', 'col2': 'VARCHAR'} )。使用此选项会禁用自动检测。 |
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 语句中不可用(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 编码(请参阅
encoding
选项)。要转换不同编码的文件,我们建议使用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
选项的默认值为 ['SQLNULL', 'BOOLEAN', 'BIGINT', 'DOUBLE', 'TIME', 'DATE', 'TIMESTAMP', 'VARCHAR']
。
CSV 函数
read_csv
自动尝试使用 CSV sniffer 找出 CSV 读取器的正确配置。它还会自动推断列的类型。如果 CSV 文件包含表头,它将使用表头中找到的名称来命名列。否则,列将命名为 column0, column1, column2, ...
。一个使用 flights.csv
文件的示例
SELECT * FROM read_csv('flights.csv');
航班日期 | 唯一承运人 | 出发城市名称 | 目的城市名称 |
---|---|---|---|
1988-01-01 | AA | 纽约,纽约州 | 洛杉矶,加利福尼亚州 |
1988-01-02 | AA | 纽约,纽约州 | 洛杉矶,加利福尼亚州 |
1988-01-03 | AA | 纽约,纽约州 | 洛杉矶,加利福尼亚州 |
路径可以是相对路径(相对于当前工作目录)或绝对路径。
我们也可以使用 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 的表(该 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 | 纽约,纽约州 | 洛杉矶,加利福尼亚州 |
1988-01-02 | AA | 纽约,纽约州 | 洛杉矶,加利福尼亚州 |
1988-01-03 | AA | 纽约,纽约州 | 洛杉矶,加利福尼亚州 |
如果我们想手动指定 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 文件。