CSV文件的PostgreSQL COPY在完成前中断。与psql \ copy一起使用,但不支持COPY

时间:2018-07-13 02:50:18

标签: python postgresql csv sqlalchemy copy

我目前正在处理我认为是相当大的文件,需要将其提取到PostgreSQL数据库中。这是.csv读取的一些示例行,COPY命令用于将这些行插入数据库。这些行的结构是,sample_id和otu_id是两个外键,它们引用样本表和otu表中的主键。

sample_id,otu_id,count
163,2901,0.0
164,2901,0.0
165,2901,0.0

使用SQLAlchemy使用以下代码将其提取到表中:

self._engine.execute(
                    text('''COPY otu.sample_otu from :csv CSV header''').execution_options(autocommit=True),
                    csv=fname)

从.csv文件复制到表后,我在数据库中查询显示的样本,它为我提供了sample_id = 163,otu_id = 2901的结果,但此后没有给出行。如果我是正确的,那么COPY命令在遇到第一个错误后便停止复制,因此我的猜测是id 164和otu id 2901的样本存在问题。

我尝试了以下操作:

  1. otu表中存在2901的有效条目,对于 样本表ID 164,所以我认为这不是丢失的键错误。

  2. 我还在文件中搜索了重复的外键组合,但似乎找不到任何组合。

  3. 我试图仅将第二个条目写入从复制的.csv文件中,以防它与.csv文件的大小有关,但最终却给了我同样的问题,但剪切在不同的地方。当仅复制带有偶数otu_id的条目时,otu_ids> 2890的后续表查询结果在样本id 152(otu id 2900)处中断。

我尝试使用psql的\ copy命令从.csv文件中手动复制:

\copy sample_otu FROM 'bpaotu-ijpgihw6' WITH DELIMITER  ',' CSV HEADER;

这似乎工作得很好。该查询显示了otu ID超过2901的otu_id。

对于它为什么会中断,我非常困惑,因为前后的.csv行看起来相同,并且它使用的外表中也有相应的主键值作为条目。

1 个答案:

答案 0 :(得分:0)

对于遇到此问题的任何人:

问题是一个简单的范围错误。我错过了python数据库导入脚本中使用block的文件上的缩进,因此它试图在完成写入文件之前从.csv文件进行COPY。因此,copy语句不会抛出错误,因为它假定文件在实际上仍在写入时已完成。

我移动了缩进,以使COPY在文件写入块关闭后运行,并且现在可以运行了。

这也解释了为什么psql \ copy命令有效,而脚本COPY却不起作用,因为手动复制是在文件已创建但无法完全导入之后进行的。