DuckDB导入CSV时无法设置主键、唯一约束等列属性的问题
DuckDB导入CSV时添加约束失效的解决方案
在DuckDB中导入CSV文件时,分隔符等基础参数可正常配置,但无法通过read_csv的columns参数直接为列添加主键(PK)、唯一约束(UNIQUE)、非空约束(NOT NULL)——手动指定约束后执行无报错,但约束实际未生效。旧版本中ALTER TABLE命令还未实现主键设置功能,导致该问题更难处理。
问题示例
data.csv内容
id,description,status 1,"lorem ipsum",active
执行的SQL语句
SELECT Prompt FROM sniff_csv('data.csv'); CREATE TABLE product AS SELECT * FROM read_csv('data.csv', auto_detect=false, delim=',', quote='"', escape='"', new_line='\n', skip=0, comment='', header=true, columns={'id': 'BIGINT PRIMARY KEY', 'description': 'VARCHAR UNIQUE', 'status': 'VARCHAR NOT NULL'}); show product;
解决方案
旧版本(v1.2之前)
read_csv的columns参数仅支持指定数据类型,不支持直接附加约束,且当时ALTER TABLE无法设置主键,需通过「先建约束表,再插入数据」的方式实现:
- 创建带有目标约束的空表:
CREATE TABLE product ( id BIGINT PRIMARY KEY, description VARCHAR UNIQUE, status VARCHAR NOT NULL );
- 将CSV数据插入到该表:
INSERT INTO product SELECT * FROM read_csv('data.csv', auto_detect=false, delim=',', quote='"', escape='"', new_line='\n', skip=0, comment='', header=true);
v1.2及以上版本
DuckDB v1.2版本已修复并实现ALTER TABLE设置主键的功能,可灵活选择两种方式添加约束:
方式一:先建约束表再插入
同旧版本的步骤,直接创建带约束的表后插入数据。
方式二:先导入数据再补加约束
- 先导入数据(仅指定数据类型):
CREATE TABLE product AS SELECT * FROM read_csv('data.csv', auto_detect=false, delim=',', quote='"', escape='"', new_line='\n', skip=0, comment='', header=true, columns={'id': 'BIGINT', 'description': 'VARCHAR', 'status': 'VARCHAR'});
- 使用
ALTER TABLE补充约束:
ALTER TABLE product ADD PRIMARY KEY (id); ALTER TABLE product ADD UNIQUE (description); ALTER TABLE product ALTER COLUMN status SET NOT NULL;
内容的提问来源于stack exchange,提问作者Ondrej profant




