如何向PostgreSQL表中插入NULL值

3

我有一个CSV文件中的数据,想用pgloader插入到postgresql表中。输入文件来自MS SQL服务器导出,并且NULL值已经明确地转换为NULL。

我的pgloader脚本似乎在关键字NULL上失败,特别是对于整数和时间戳字段。

我真的不知道我缺少什么。您的帮助将不胜感激。

我可以成功地从psql控制台插入到表中:

insert into raw.a2
(NUM , F_FILENO , F_FOLIONO , F_DOC_TYPE , F_DOCDATE , F_BATCH , F_BOX , F_BLUCPY , F_ROUTOPOST , F_ROUTOUSR , F_WFCREATE , LINKEDFILE , DATECREATE , USERCREATE , DATEUPDATE , USERUPDATE , MEDIA , PGCOUNT , GROUPNUM , SUBJECT , PRI , F_FILECAT)
values
(
16,'18',3,'Nomination Details',NULL,NULL,NULL,1,NULL,NULL,1,'00000016.TIF','2011-02-08 13:02:11.000','isaac','2012-01-12 08:52:31.000','henrey','Multi',4,1.0,0,'-',NULL
);

插入成功,插入了1条数据。

文件示例

1,'6',1,'Details',2011-02-22 00:00:00.000,NULL,NULL,1,NULL,NULL,2,'00000001.TIF',2011-02-08 09:42:24.000,'kevin',2011-10-27 09:08:42.000,'james','Multi',1,1.0,0,'-',NULL
2,'6',2,'Bio data',NULL,NULL,NULL,1,NULL,NULL,2,'00000002.TIF',2011-02-08 10:25:11.000,'kevin',2012-11-19 16:20:49.000,'pattie','Multi',4,1.0,0,'-',NULL
4,'10',1,'Details',2011-02-22 00:00:00.000,NULL,NULL,1,NULL,NULL,2,'00000004.TIF',2011-02-08 10:43:38.000,'kevin',2014-07-18 10:46:06.000,'brian','Multi',1,1.0,0,'-',NULL

pgloader 命令

pgloader --type csv --with truncate --with "fields optionally enclosed by '''" --with "fields terminated by ','" --set "search_path to 'raw'" - "postgresql://postgres:postgres@localhost/doc_db?a2" < null_test

表格
                               Table "raw.a2"
   Column    |            Type             | Collation | Nullable | Default 
-------------+-----------------------------+-----------+----------+---------
 num         | integer                     |           | not null | 
 f_fileno    | character varying(15)       |           |          | 
 f_foliono   | integer                     |           |          | 
 f_doc_type  | character varying(50)       |           |          | 
 f_docdate   | timestamp without time zone |           |          | 
 f_batch     | integer                     |           |          | 
 f_box       | integer                     |           |          | 
 f_blucpy    | integer                     |           |          | 
 f_routopost | integer                     |           |          | 
 f_routousr  | character varying(49)       |           |          | 
 f_wfcreate  | integer                     |           |          | 
 linkedfile  | character varying(255)      |           |          | 
 datecreate  | timestamp without time zone |           |          | 
 usercreate  | character varying(50)       |           |          | 
 dateupdate  | timestamp without time zone |           |          | 
 userupdate  | character varying(50)       |           |          | 
 media       | character varying(5)        |           |          | 
 pgcount     | smallint                    |           |          | 
 groupnum    | double precision            |           |          | 
 subject     | smallint                    |           |          | 
 pri         | character varying(1)        |           |          | 
 f_filecat   | character varying(50)       |           |          | 

索引:

"a2_pkey" 主键, btree (num)

输出/错误

2019-07-24T05:55:24.231000Z WARNING Target table "\"raw\".\"a2\"" has 1 indexes defined against it.
2019-07-24T05:55:24.237000Z WARNING That could impact loading performance badly.
2019-07-24T05:55:24.237000Z WARNING Consider the option 'drop indexes'.
2019-07-24T05:55:24.460000Z ERROR PostgreSQL ["\"raw\".\"a2\""] Database error 22P02: invalid input syntax for integer: "NULL"
CONTEXT: COPY a2, line 1, column f_batch: "NULL"
2019-07-24T05:55:24.461000Z ERROR PostgreSQL ["\"raw\".\"a2\""] Database error 22007: invalid input syntax for type timestamp: "NULL"
CONTEXT: COPY a2, line 1, column f_docdate: "NULL"

尝试将文件中的NULL替换为空字符串(不带引号),例如:1,'6',1,'Details',2011-02-22 00:00:00.000,,,1,,,2,'00000001.TIF',... - Nir Alfasi
1
这个已经成功了。非常感谢。 现在我只需要更新我的SQL服务器导出脚本,以便在NULL值的位置输出""而不是文本NULL。 - Grooth
1个回答

1

pgloader 文档 中:

null if

该选项需要一个参数,可以是关键字 blanks 或用双引号括起来的字符串。

当使用 blanks 并且读取的字段值仅包含空格字符时,它会自动转换为 SQL 的 NULL 值。

当使用双引号括起来的字符串并将其读取为字段值时,该字段值会自动转换为 SQL 的 NULL 值。

看起来你的命令中缺少 --with 'null if "NULL"'

否则,你应该能够直接从 psql 加载 CSV 数据。

\copy raw.a2 (NUM, F_FILENO, F_FOLIONO, F_DOC_TYPE, F_DOCDATE, F_BATCH, F_BOX, F_BLUCPY, F_ROUTOPOST, F_ROUTOUSR, F_WFCREATE, LINKEDFILE, DATECREATE, USERCREATE, DATEUPDATE, USERUPDATE, MEDIA, PGCOUNT, GROUPNUM, SUBJECT, PRI, F_FILECAT) FROM 'file.csv' WITH (FORMAT csv, NULL 'NULL')

非常感谢。 我尝试了那个,但似乎它要么是pgloader不理解的指令,要么我必须提供更多的参数来使用那个指令。 现在我可能只能暂时用空字符串替换输入字符串中的“NULL”文本。 - Grooth
你可能想尝试像第一个例子行中那样省略空字段,例如:"1,'6',1,'Details',2011-02-22 00:00:00.000,,,1,,,2,'00000001.TIF',..."。将其更改为""可能会导致生成长度为0的字符串。在Postgres中,NULL和长度为0的字符串是不同的。 - Belayer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接