如何将整个文件作为一个字符串导入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可以提供。
答案 0 :(得分:3)
如果你真的必须用bash来做,你需要手动做一些事情:
psql regress -c "insert into text_files(file_content) values ('$(sed "s/'/''/g" test.txt)');"
但它会有点脆弱。我个人建议使用更复杂的脚本语言。它还会将整个文件至少加载到内存中几次。
psql
有\lo_import
,但会将文件导入pg_largeobject
,而不是text
字段。
答案 1 :(得分:1)
这是由文档制作的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()
答案 2 :(得分:0)
例如,你有这个文件:
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 );
它会将创建表格行合并为一个,这是你要找的吗?
答案 3 :(得分:0)
我最终使用临时表,其中文件按行存储。
表格设计:
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
这仅适用于没有$
字符的文件 - 我文件中唯一可用的字符。