通过psql导入CSV时非空约束默认值列报错求助
解决PostgreSQL COPY导入CSV时默认值不生效的问题
问题原因
PostgreSQL的COPY命令不会自动触发列的默认值逻辑:
- 当CSV中存在
col2列但值为空时,会被当作NULL插入,违反NOT NULL约束; - 当CSV中移除
col2列时,若COPY未指定导入列,会因缺少数据报错。
解决方案
方案一:修改COPY命令,仅导入有效数据列
直接在COPY语句中指定要导入的列(仅col1),未指定的col2会自动使用定义的默认值CURRENT_TIMESTAMP。
修正后的Perl命令(注意修正原代码中shema_name的拼写错误):
my $cmd = "/usr/bin/psql -h $host -d $dbname -p $port -U $user -c \"\\COPY ${schema_name}.$table_name (col1) FROM '$csvFile' WITH CSV HEADER DELIMITER '$delimiter'\";";
该方案适用于CSV中col2列存在但无有效数据,或直接移除col2列的场景。
方案二:通过临时表处理带空值的col2列
若必须保留CSV的col2列结构,可先将数据导入临时表,再通过INSERT语句将数据同步至正式表,同时替换空值为默认值:
修改后的Perl命令:
my $cmd = "/usr/bin/psql -h $host -d $dbname -p $port -U $user -c \"CREATE TEMP TABLE temp_table (col1 varchar(50) NOT NULL, col2 timestamp(6)); \\COPY temp_table FROM '$csvFile' WITH CSV HEADER DELIMITER '$delimiter'; INSERT INTO ${schema_name}.$table_name (col1, col2) SELECT col1, COALESCE(col2, CURRENT_TIMESTAMP) FROM temp_table; DROP TABLE temp_table;\"";
原理是利用COALESCE函数将col2的空值替换为CURRENT_TIMESTAMP,满足NOT NULL约束的同时应用默认值逻辑。
内容的提问来源于stack exchange,提问作者JanFi86
相关产品推荐
相关产品推荐

