将整个文件作为一个字符串导入



如何将整个文件作为一个字符串导入到postgresql?

create table text_files (
  id serial primary key,
  file_content text
);

我已经尝试过copy text_files (file_content) from /home/test.txt,但这将在文本文件中每行创建一行。

我有数百个小文本文件,我想在里面使用一些带有copy的bash循环。

更新:如果BASH和copy不是此任务的最佳工具,我可以使用其他编程语言 - 也许Python可以提供任何东西。

如果您确实必须在bash中进行此操作,则需要手工做一些:

psql regress -c "insert into text_files(file_content) values ('$(sed "s/'/''/g" test.txt)');"

,但这会有点脆弱。我建议亲自使用更精致的脚本语言。它还将整个文件至少将整个文件加载到内存中。

psql具有lo_import,但是将文件导入pg_largeobject,而不是text字段。

这是由文档制成的Python中的一个基本示例!

请注意,没有使用try catch块(这很糟糕),但应该起作用。您可能最终会出现UTF-8错误,IO错误或我不理解的内容(如有必要,我会修改代码)...无论如何,将下面的代码保存到文件中(例如," myfile.py"),放置正确的信息以连接到数据库,用真实路径替换"/path/to/files/",最后在控制台中运行" python myfile.py"。

如果您有很多文件,这可能会花费一些,并注意系统的内存状态。每个文件将被读取并放入系统的内存中。如果文件大小超过内存限制,则脚本可能会崩溃。如果文件很小,则很好。

首先测试!

要求:安装了psycopg2的Python

import os
import psycopg2
connection = psycopg2.connect(database='my_db', user='my_postgres_user', password='my_postgres_pass')
cursor = connection.cursor()
cursor.execute('DROP TABLE IF EXISTS text_files;CREATE TABLE text_files (id SERIAL UNIQUE PRIMARY KEY, file_name TEXT, file_content TEXT);')
directory = os.path.normpath('/path/to/files/')
for root, dirs, files in os.walk(directory):
  for filename in files:
    print filename
    with open(os.path.join(root, filename), 'rb+') as f:
      cursor.execute('INSERT INTO text_files (file_name, file_content) VALUES (%s, %s);', (filename, f.read()))
    f.closed  
connection.commit()
cursor.close()
connection.close()

例如,您有此文件:

test
test
create table text_files (
  id serial primary key,
  file_content text
);
test
create table text_files (
  id serial primary key,
  file_content text
);

运行sed命令:

sed '/(/{:a;N;/)/!ba};s/n/ /g' file
test
test
create table text_files (   id serial primary key,   file_content text );
test
create table text_files (   id serial primary key,   file_content text );

它将将创建表线合并为一个,这是您要寻找的吗?

我最终使用了临时表,其中文件存储在行中。

表设计:

drop table if exists text_files_temp;
create table text_files_temp (
  id serial primary key,
  file_content text
);
drop table if exists text_files;
create table text_files (
  id serial primary key,
  file_name text,
  file_content text
);

bash脚本:

#!/bin/sh
for f in /home/tgr/tmp/*
do
  psql -c"delete from text_files_temp;"
  psql -c"copy text_files_temp (file_content) from $f delimiter '$'"
  psql -c"insert into text_files (file_content) select array_to_string(array_agg(file_content order by id),E'n') from text_files_temp;"
  psql -c"update text_files set file_name = '$f' where file_name is null;"    
done

这仅适用于没有$字符的文件 - 我的文件中唯一可能的字符。

相关内容

  • 没有找到相关文章

最新更新