Examples
以下示例使用 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'
});
从标准输入读取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
语句创建表,而无需手动指定模式:
CREATE TABLE ontime AS
SELECT * FROM 'flights.csv';
我们可以使用FROM
-first syntax来省略SELECT *
。
CREATE TABLE ontime AS
FROM 'flights.csv';
将查询结果写入CSV文件。
COPY (SELECT * FROM ontime) TO 'flights.csv' WITH (HEADER, DELIMITER '|');
如果我们序列化整个表,我们可以简单地用它的名称来引用它。
COPY ontime TO 'flights.csv' WITH (HEADER, DELIMITER '|');
CSV Loading
CSV加载,即将CSV文件导入数据库,是一个非常常见但又出奇棘手的任务。虽然CSV表面看起来简单,但CSV文件中存在许多不一致之处,这使得加载它们成为一个挑战。CSV文件有许多不同的种类,经常损坏,并且没有模式。CSV阅读器需要应对所有这些不同的情况。
DuckDB CSV 阅读器可以通过使用 CSV 嗅探器 分析 CSV 文件来自动推断要使用的配置标志。在大多数情况下,这将正常工作,应该是首先尝试的选项。在极少数情况下,如果 CSV 阅读器无法确定正确的配置,可以手动配置 CSV 阅读器以正确解析 CSV 文件。有关更多信息,请参阅 自动检测页面。
Parameters
以下是可以传递给CSV阅读器的参数。这些参数被read_csv
函数接受。但并非所有参数都被COPY
语句接受。
Name | Description | Type | Default |
---|---|---|---|
all_varchar |
用于跳过CSV解析中的类型检测并假设所有列均为VARCHAR 类型的选项。此选项仅由read_csv 函数支持。 |
BOOL |
false |
allow_quoted_nulls |
允许将引用的值转换为NULL 值的选项 |
BOOL |
true |
auto_detect |
启用 CSV参数的自动检测。 | BOOL |
true |
auto_type_candidates |
此选项允许您指定嗅探器在检测CSV列类型时将使用的类型。VARCHAR 类型始终包含在检测到的类型中(作为备用选项)。请参阅 示例。 |
TYPE[] |
默认类型 |
columns |
一个结构体,指定CSV文件中包含的列名和列类型(例如,{'col1': 'INTEGER', 'col2': 'VARCHAR'} )。使用此选项意味着不使用自动检测。 |
STRUCT |
(空) |
compression |
文件的压缩类型。默认情况下,这将根据文件扩展名自动检测(例如,t.csv.gz 将使用 gzip,t.csv 将使用 none )。选项包括 none 、gzip 、zstd 。 |
VARCHAR |
auto |
dateformat |
指定解析日期时使用的日期格式。请参阅日期格式。 | VARCHAR |
(空) |
decimal_separator |
数字的小数分隔符。 | VARCHAR |
. |
delimiter |
指定文件中每行(行)内列的分隔符。是sep 的别名。此选项仅在COPY 语句中可用。 |
VARCHAR |
, |
delim |
指定文件中每行(行)内分隔列的分隔符字符。sep 的别名。 |
VARCHAR |
, |
escape |
指定在数据字符序列与quote 值匹配时应出现在前面的字符串。 |
VARCHAR |
" |
filename |
Whether or not an extra filename column should be included in the result. |
BOOL |
false |
force_not_null |
不要将指定列的值与NULL 字符串匹配。在默认情况下,NULL 字符串为空,这意味着空值将被读取为零长度字符串而不是NULL 。 |
VARCHAR[] |
[] |
header |
指定文件包含一个标题行,其中包含文件中每列的名称。 | BOOL |
false |
hive_partitioning |
Whether or not to interpret the path as a Hive partitioned path. | BOOL |
false |
ignore_errors |
忽略遇到的任何解析错误的选项 – 并忽略有错误的行。 | BOOL |
false |
max_line_size |
最大行大小(以字节为单位)。 | BIGINT |
2097152 |
names |
列名作为列表,参见示例。 | VARCHAR[] |
(空) |
new_line |
设置文件中的换行符。选项为 '\r' ,'\n' , 或 '\r\n' 。请注意,CSV解析器仅区分单字符和双字符的行分隔符。因此,它不会区分 '\r' 和 '\n' 。 |
VARCHAR |
(空) |
normalize_names |
布尔值,指定是否应规范化列名,从中删除任何非字母数字字符。 | BOOL |
false |
null_padding |
如果启用此选项,当一行缺少列时,它将在右侧用NULL 值填充剩余的列。 |
BOOL |
false |
nullstr |
指定表示NULL 值的字符串或(自v0.10.2起)表示NULL 值的字符串列表。 |
VARCHAR 或 VARCHAR[] |
(空) |
parallel |
是否使用并行CSV读取器。 | BOOL |
true |
quote |
指定在引用数据值时使用的引用字符串。 | VARCHAR |
" |
sample_size |
用于参数自动检测的样本行数。 | BIGINT |
20480 |
sep |
指定文件中每行(行)内列的分隔符字符。delim 的别名。 |
VARCHAR |
, |
skip |
文件顶部要跳过的行数。 | BIGINT |
0 |
timestampformat |
指定解析时间戳时使用的日期格式。请参阅日期格式。 | VARCHAR |
(空) |
types 或 dtypes |
列类型可以是列表(按位置)或结构体(按名称)。示例在此。 | VARCHAR[] 或 STRUCT |
(空) |
union_by_name |
是否应该通过名称而不是位置来统一多个模式的列。请注意,使用此选项会增加内存消耗。 | BOOL |
false |
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');
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 |
路径可以是相对路径(相对于当前工作目录)或绝对路径。
我们可以使用 read_csv
来创建一个持久表:
CREATE TABLE ontime AS
SELECT * FROM read_csv('flights.csv');
DESCRIBE ontime;
column_name | column_type | null | key | default | extra |
---|---|---|---|---|---|
FlightDate | DATE | YES | NULL | NULL | NULL |
UniqueCarrier | VARCHAR | 是 | NULL | NULL | NULL |
出发城市名称 | VARCHAR | 是 | 空 | 空 | 空 |
目的地城市名称 | VARCHAR | 是 | 空 | 空 | 空 |
SELECT * FROM read_csv('flights.csv', sample_size = 20_000);
如果我们明确设置delim
/sep
、quote
、escape
或header
,我们可以绕过该特定参数的自动检测:
SELECT * FROM read_csv('flights.csv', header = true);
Multiple files can be read at once by providing a glob or a list of files. Refer to the multiple files section for more information.
使用COPY
语句进行写入
COPY
语句 可用于将数据从CSV文件加载到表中。此语句的语法与PostgreSQL中使用的语法相同。要使用 COPY
语句加载数据,我们首先必须创建一个具有正确模式的表(该模式与CSV文件中的列顺序匹配,并使用适合CSV文件中值的类型)。COPY
会自动检测CSV的配置选项。
CREATE TABLE ontime (
flightdate DATE,
uniquecarrier VARCHAR,
origincityname VARCHAR,
destcityname VARCHAR
);
COPY ontime FROM 'flights.csv';
SELECT * FROM ontime;
航班日期 | 唯一承运人 | 出发城市名称 | 目的地城市名称 |
---|---|---|---|
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 文件页面。
Limitations
CSV 读取器仅支持使用 UTF-8 字符编码的输入文件。对于使用不同编码的 CSV 文件,可以使用例如 iconv
命令行工具 将其转换为 UTF-8。例如:
iconv -f ISO-8859-2 -t UTF-8 input.csv > input-utf-8.csv
顺序保持
CSV 读取器遵循 preserve_insertion_order
配置选项 以 保留插入顺序。
当 true
(默认值)时,CSV 读取器返回的结果集中的行顺序与从文件中读取的相应行的顺序相同。
当 false
时,不能保证顺序被保留。