我有一个包含3200万个元组的数据集,我正在使用COPY FROM将这些元组复制到表中。在前700万个元组中,有3个格式不正确。在这些情况下,下一个记录不是在当前记录下面,而是追加到同一行上当前记录的末尾。因此,
record1
record2
它是
record1record2
我通过导航到应该换行的地方并在每个示例中按一次"Enter"键(典型的换行符输入)来修复这个问题。一旦我修复了这些行,COPY函数就可以完全正确地读取它们。对我来说,这意味着"Enter"是插入换行符的有效方法,因为COPY函数可以毫无问题地读取那些"Enter"生成的换行符。
然而,后来当我通过第700万个元组时,我遇到了:
ERROR: literal newline found in data
HINT: Use "\n" to represent newline.
Context: COPY time_raw, line 7308000
SQL状态:22P04
我查看了该记录的数据,发现它与其上或其下的记录没有什么不同。为了确定这一点,我在记录7308000的开头按了"Backspace"键,将其上移一行到记录7307999的结尾。就像上面的格式record1record2一样。然后我按了"Enter"以确保开始记录7308000的换行符将与COPY先前毫不费力地接受的字符相同。结束记录7307999的换行符与我用来分隔早期格式不正确的记录的换行符完全相同(再一次,COPY没有问题地加入了这个换行符)。为了覆盖我的基础,我对记录7308001做了同样的操作,确保结束记录7308000的新行与我之前输入的新行相同,COPY接受此操作。但是,在保存并尝试再次从文件复制时,我得到:
ERROR: literal newline found in data
HINT: Use "\n" to represent newline.
Context: COPY time_raw, line 7307999
很明显,错误上移了,COPY之前接收的换行符突然变得无效。我再次查看数据,将7307999的开头移到7307998的结尾,然后按"Enter"键插入一个换行符,COPY一直认为该字符对700多万条记录有效。因此,此时,我确信7307998的结尾是一个换行符,应该已经证明了它在COPY中是有效的。我再次运行查询,现在我得到:
ERROR: literal newline found in data
HINT: Use "\n" to represent newline.
Context: COPY time_raw, line 7307998
错误又上升了。据我所知,我只是放入了和我之前做的相同的"输入"新行字符,由于某种原因,过去的7308000副本将它们读为无效。
这些是数据集的第7307996 - 7308000行(56列,大部分无意义)
2012-02-23T13:10:03.1769237+00:00 9863996 12604 13807 8171 0000 0001 0000 0000 0000 0000 0000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2012-02-23T13:10:03.1869189+00:00 9863997 12604 13807 8171 0000 0001 0000 0000 0000 0000 0000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2012-02-23T13:10:03.1969230+00:00 9863998 12604 13807 8171 0000 0001 0000 0000 0000 0000 0000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2012-02-23T13:10:03.2069124+00:00 9863999 12604 13807 8171 0000 0001 0000 0000 0000 0000 0000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2012-02-23T13:10:03.2169261+00:00 9864000 12604 13807 8171 0000 0001 0000 0000 0000 0000 0000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
我在stackoverflow编辑器中的每条记录后添加了一个"Enter",以便一条接一条地显示它们,但关键是相关的中间行(7307998)的格式与其他文件完全相同,并且我确保它被换行符包围,这些换行符已经被COPY函数显示为有效字符。每当我试图确保记录周围的换行符与我之前使用的换行符相同时,错误就会向上移动一行,我不知道在这种情况下该怎么办。
我的疑问是:
copy time_raw from E'C:\\Users\\bozon92\\Documents\\YorkU\\Summer 2016\\4080 Project\\Other Files\\allData.txt';
我试过将"with(format csv,delimiter '\t')"附加到后面,但这告诉我COPY delimiter必须是一个单字节字符,而"with(format csv,delimiter'')"(''是一个文本制表符空格,而不是\t)给我带来了相同性质的错误,只是语法略有不同:
ERROR: unquoted newline found in data
HINT: Use quoted CSV field to represent newline.
CONTEXT: COPY time_raw, line 7307998
只是"未引用"而不是"字面"。
作为说明,我已经被告知我可以只将数据削减到700万个元组,我可能最终会这样做,但我想知道为什么会发生这个问题,这样我就可以在未来避免它。我不知道数据有什么问题,因为那些特定的记录看起来完全正常,格式与它之前和之后的记录完全相同,那么,我该如何处理这个文字换行符问题呢?我不知道该如何处理,因为我甚至找不到错误的痕迹。
5条答案
按热度按时间ukdjmx9f1#
根据PostgreSQL源代码片段
copy.c
:这意味着你的输入数据在你的字符串中的某个地方使用了字节
0x0A
,例如你使用了"abcNxyz"
,而不是N
,实际上有一个值为0x0A
的字节。解决方法是使用字符串
"abc\n"
,你应该能够找到所有虚假的换行符,并使用一些脚本(可能是Python或Perl)将它们替换为\n
。kyvafyod2#
如果您有权访问提取元组的源系统,则可以选择在提取数据时替换所有换行符:
这将用一个空格代替行尾字符。这为我的情况修复了
ERROR: literal newline found in data
。xiozqbni3#
您要导入的转储文件可能以
\r (0x0D)
结尾,而不是\r\n (0x0D 0x0A)
,从而导致这个错误,这是我遇到的情况。ktca8awb4#
使用ATOM或类似的文本编辑器,使用Regex搜索并将[\r\n]+替换为\n。尽管它可能会因超过1M行而锁定。
cig3rfwq5#
在Linux中,我用这三个命令解决了