postgresql 值对于类型字符变化太长(512)--为什么无法导入数据?

vfwfrxfs  于 2023-02-08  发布在  PostgreSQL
关注(0)|答案(1)|浏览(429)

Postgres中有限字符类型(例如varchar(n))的最大大小为10485760。
description on max length of postgresql's varchar
请下载文件进行测试并将其解压到/tmp/2019q4中,我们仅使用pre.txt导入数据。
sample data
输入你的psql并创建一个数据库:

postgres=# create database edgar;
postgres=# \c edgar;

根据网页创建表格:
fields in pre table definations

edgar=# create table pre(
  id serial ,
  adsh varchar(20),
  report numeric(6,0),
  line  numeric(6,0),
  stmt varchar(2),
  inpth  boolean,
  rfile char(1),
  tag  varchar(256),
  version varchar(20),
  plabel varchar(512),
  negating boolean
);
CREATE TABLE

尝试导入数据:

edgar=# \copy pre(adsh,report,line,stmt,inpth,rfile,tag,version,plabel,negating) from '/tmp/2019q4/pre.txt' with delimiter  E'\t' csv header;

我们分析错误信息:

ERROR:  value too long for type character varying(512)
CONTEXT:  COPY pre, line 1005798, column plabel: "LIABILITIES AND STOCKHOLDERS EQUITY   0
0001493152-19-017173    2   11  BS  0   H   LiabilitiesAndStockholdersEqu..."
Time: 1481.566 ms (00:01.482)

1.我在字段中设置的大小正好是512,比10485760小很多。2.第1005798行的内容与错误信息中的内容不一样:

0001654954-19-012748    6   20  EQ  0   H   ReclassificationAdjustmentRelatingToAvailableforsaleSecuritiesNetOfTaxEffect    0001654954-19-012748    Reclassification adjustment relating to available-for-sale securities, net of tax effect"   0

现在我删除前面的表,将plabel字段转换为text,重新创建它:

edgar=# drop table pre;
DROP TABLE
Time: 22.763 ms
edgar=# create table pre(
  id serial ,
  adsh varchar(20),
  report numeric(6,0),
  line  numeric(6,0),
  stmt varchar(2),
  inpth  boolean,
  rfile char(1),
  tag  varchar(256),
  version varchar(20),
  plabel text,
  negating boolean
);
CREATE TABLE
Time: 81.895 ms

使用相同的复制命令导入相同的数据:

edgar=# \copy pre(adsh,report,line,stmt,inpth,rfile,tag,version,plabel,negating) from '/tmp/2019q4/pre.txt' with delimiter  E'\t' csv header;
COPY 275079
Time: 2964.898 ms (00:02.965)
edgar=#

psql控制台中没有错误信息,让我检查原始数据“/tmp/2019q4/pre.txt”,其中包含1043000行。

wc -l  /tmp/2019q4/pre.txt
1043000 /tmp/2019q4/pre.txt

有1043000行,那么导入了多少行呢?

edgar=# select count(*) from pre;
 count  
--------
 275079
(1 row)

为什么导入的数据少而没有错误信息?

nukf8bse

nukf8bse1#

您提供的示例数据显然不是您真正加载的数据,它确实仍然显示相同的错误,但当然行号和标记是不同的。
该文件偶尔会在应该有单引号(撇号)的地方出现双引号。因为您使用的是CSV模式,这些杂散的双引号将开始多行字符串,这些字符串一直延伸到下一个杂散的双引号。这就是为什么数据行比输入行少的原因,因为数据值是巨大的多行字符串。
由于您的数据显然不是CSV,您可能不应该使用CSV格式的\copy。只要您指定“header”,它就可以很好地加载文本格式,尽管该选项直到v15才在文本格式中可用。对于在此之前的版本,您可以手动删除标题行,或使用PROGRAM跳过标题,如FROM PROGRAM 'tail +2 /tmp/pre.txt'。或者,您可以继续使用CSV格式,但请选择一个不同的引号字符,一个永远不会出现在数据中的字符,例如with (delimiter E'\t', format csv, header, quote E'\b')

相关问题