2

这是我在 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)

此代码和其他变体不起作用 - 我不断收到语法错误。谁能帮我完成这项任务?谢谢!!

4

3 回答 3

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() Temp 表会在之后销毁cur.close()

于 2014-02-01T02:13:51.767 回答
2

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

反过来是不正确的。你不能COPY (SELECT ....) FROM ... 。如果它是一个简单的SELECTPostgreSQL 可以尝试假装它是一个视图,但实际上它没有多大意义,并且无论如何它会应用于目标表,而不是行。所以你写的代码不会做你认为它做的事,即使它有效。

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

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

于 2014-02-01T05:07:45.170 回答
0

从 PostgreSQL 12 开始,您可以在语句中添加WHERE子句,COPY您将只获得与条件匹配的行。所以你的COPY陈述可能看起来像:

COPY table 
 FROM '/full/path/to/file.csv' 
 WITH( FORMAT CSV, HEADER, DELIMITER ',' )
 WHERE yyyymmddpst LIKE 20140131
于 2020-08-12T07:50:33.140 回答