如何将整个文件作为一个字符串导入到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
这仅适用于没有$
字符的文件 - 我的文件中唯一可能的字符。