我想从文本文件(近1GB)中提取信息并将其存储在PostgreSQL数据库中。 文本文件的格式如下:
DEBUG, 2017-03-23T10:02:27+00:00, ghtorrent-40 -- ghtorrent.rb:Repo EFForg/https-everywhere exists
DEBUG, 2017-03-24T12:06:23+00:00, ghtorrent-49 -- ghtorrent.rb:Repo Shikanime/print exists
...
我想从每一行中提取“ DEBUG”,时间戳,“ ghtorrent-40”,“ ghtorrent”和“ Repo EFForg / https-everywhere存在”,并将其存储在数据库中。
我已经使用其他语言(例如python(psycopg2)和C ++(libpqxx))完成了此操作,但是是否可以在PostgreSQL本身中编写一个函数来导入整个数据。
我目前正在使用PostgreSQL的pgAdmin4工具。 我考虑在函数中使用类似pg_read_file的文件来读取文件,但一次只能读取一行并将其插入表中。
答案 0 :(得分:2)
我用于130GB或更大的大型XML文件的一种方法是将整个文件上传到临时的 unlogged 表中,然后从中提取所需的内容。 Unlogged tables
并不安全,但是比记录日志要快得多,这完全适合临时表的目的;-)
考虑下表..
CREATE UNLOGGED TABLE tmp (raw TEXT);
..您可以使用单行psql
从控制台(unix)导入此1GB文件。.
$ cat 1gb_file.txt | psql -d db -c "COPY tmp FROM STDIN"
此后,您所需要做的就是应用逻辑来查询和提取所需的信息。根据表的大小,您可以从SELECT
创建第二个表,例如:
CREATE TABLE t AS
SELECT
trim((string_to_array(raw,','))[1]) AS operation,
trim((string_to_array(raw,','))[2])::timestamp AS tmst,
trim((string_to_array(raw,','))[3]) AS txt
FROM tmp
WHERE raw LIKE '%DEBUG%' AND
raw LIKE '%ghtorrent-40%' AND
raw LIKE '%Repo EFForg/https-everywhere exists%'
根据您的逻辑调整string_to_array
函数和WHERE
子句! (可选)您可以将这些多个LIKE
操作替换为单个SIMILAR TO
。
..,您的数据将可以使用以下方式播放:
SELECT * FROM t;
operation | tmst | txt
-----------+---------------------+------------------------------------------------------------------
DEBUG | 2017-03-23 10:02:27 | ghtorrent-40 -- ghtorrent.rb:Repo EFForg/https-everywhere exists
(1 Zeile)
提取数据后,您可以DROP TABLE tmp;
释放一些磁盘空间;)
进一步阅读:COPY
,PostgreSQL array functions
和pattern matching