Postgres从CSV表中复制选择行

时间:2014-01-31 23:40:04

标签: python-2.7 windows-7 postgresql-9.3 import-from-csv

这是我第一篇关于stackoverflow的帖子。你的论坛非常有用,因为我在过去的6个月里一直在学习Python和Postgres,我还没有发布。但是这项任务让我感到沮丧,我认为我需要开始赚取声望点:

我正在创建一个python脚本,用于每天将数据备份到SQL数据库中。我有一个带有整整几个月的小时数据的CSV文件,但我只想从文件中选择一天的数据并将这些选择的行复制到我的数据库中。我能查询CSV表并将查询结果附加到我的数据库中吗?例如:

        sys.stdin = open('file.csv', 'r')    
        cur.copy_expert("COPY table FROM STDIN 
                         SELECT 'yyyymmddpst LIKE 20140131' 
                         WITH DELIMITER ',' CSV HEADER", sys.stdin)

此代码和其他变体无法解决 - 我不断收到语法错误。任何人都可以帮我完成这项任务吗?谢谢!

3 个答案:

答案 0 :(得分:4)

首先需要创建临时表:

cur.execute('CREATE TEMPORARY TABLE "temp_table" (LIKE "your_table") WITH OIDS')

比从csv复制数据:

cur.execute("COPY temp_table FROM '/full/path/to/file.csv' WITH CSV HEADER DELIMITER ','")

插入必要的记录:

cur.execute("INSERT INTO your_table SELECT * FROM temp_table WHERE yyyymmddpst LIKE 20140131")

不要忘记做conn.commit() 临时表将在cur.close()

之后销毁

答案 1 :(得分:1)

你可以COPY (SELECT ...) TO一个外部文件,因为PostgreSQL只需要从查询中读取行并将它们发送到客户端。

反之则不然。你不能COPY (SELECT ....) FROM ...。如果它是一个简单的SELECT PostgreSQL可以尝试假装它是一个视图,但实际上它没有多大意义,并且无论如何它都适用于 target 表,不是行。所以你写的代码不会做你认为它做的,即使它有用。

在这种情况下,您可以创建一个unloggedtemporary表,将完整的CSV复制到该表,然后使用SQL提取您想要的行,正如Dmitry所指出的那样。

另一种方法是使用the file_fdw将CSV文件映射为表格。 CSV没有被复制,它只是按需读取。这使您可以跳过临时表步骤。

答案 2 :(得分:0)

在PostgreSQL 12中,您可以在WHERE语句中添加COPY子句,您将仅获得与条件匹配的行。 因此,您的COPY语句看起来像:

COPY table 
 FROM '/full/path/to/file.csv' 
 WITH( FORMAT CSV, HEADER, DELIMITER ',' )
 WHERE yyyymmddpst LIKE 20140131