如何将(文件)数据插入PostgreSQL bytea列中?
-
16-10-2019 - |
题
这个问题与Byteav。Oidv。Blobs诉大对象等有关。
我有一个包含主钥匙的桌子 integer
字段和a bytea
场地。我想将数据输入到 bytea
场地。大概可以由其中之一来完成 PL/
语言,我可能会考虑这样做 PL/Python
在将来。
当我仍在进行测试和实验时,我只想使用“标准” SQL语句从文件(在服务器上)插入数据。我知道,只有在服务器上具有写入权限的管理员才能以我想要的方式插入数据。我不担心这个阶段,因为用户不会插入 bytea
目前数据。我已经搜索了各种stackexchange网站,PostgreSQL档案和Internet,但无法找到答案。
编辑: 这个 2008年的讨论意味着我想做的是不可能的。如何 bytea
那么使用字段?
编辑: 这个 从2005年开始的类似问题仍未得到答复。
解决了: 提供的详细信息 这里 在 psycopg
网站为我用Python编写的解决方案提供了基础。也可能将二进制数据插入 bytea
列使用 PL/Python
. 。我不知道使用“纯” SQL是否可以。
解决方案
作为超级用户:
create or replace function bytea_import(p_path text, p_result out bytea)
language plpgsql as $$
declare
l_oid oid;
begin
select lo_import(p_path) into l_oid;
select lo_get(l_oid) INTO p_result;
perform lo_unlink(l_oid);
end;$$;
lo_get
是在9.4中引入的,因此对于较旧版本,您需要:
create or replace function bytea_import(p_path text, p_result out bytea)
language plpgsql as $$
declare
l_oid oid;
r record;
begin
p_result := '';
select lo_import(p_path) into l_oid;
for r in ( select data
from pg_largeobject
where loid = l_oid
order by pageno ) loop
p_result = p_result || r.data;
end loop;
perform lo_unlink(l_oid);
end;$$;
然后:
insert into my_table(bytea_data) select bytea_import('/my/file.name');
其他提示
利用 pg_read_file('location_of file')::bytea
.
例如,
create table test(id int, image bytea);
insert into test values (1, pg_read_file('/home/xyz')::bytea);
该解决方案在运行时并不是很有效的,但是与制作自己的标题相比,这在很容易 COPY BINARY
. 。此外,它不需要任何库或脚本语言。
首先,将文件转换为六个人,使文件大小加倍。 xxd -p
让我们非常接近,但是它带来了一些我们必须照顾的烦人的新线:
xxd -p /path/file.bin | tr -d '\n' > /path/file.hex
接下来,将数据导入PostgreSQL中的数据很大 text
场地。这种类型的每个字段值最多可容纳一个GB,因此我们应该出于大多数目的可以:
CREATE TABLE hexdump (hex text); COPY hexdump FROM '/path/file.hex';
现在我们的数据是一个无用的大十六进制字符串,我们使用PostgreSQL的 decode
将其变成一个 bytea
类型:
CREATE TABLE bindump AS SELECT decode(hex, 'hex') FROM hexdump;
这 用xxd回答 很好,对于小文件,非常快。以下是我正在使用的示例脚本。
xxd -p /home/user/myimage.png | tr -d '\n' > /tmp/image.hex
echo "
-- CREATE TABLE hexdump (hex text);
DELETE FROM hexdump;
COPY hexdump FROM '/tmp/image.hex';
-- CREATE TABLE bindump (binarydump bytea);
DELETE FROM bindump;
INSERT INTO bindump (binarydump)
(SELECT decode(hex, 'hex') FROM hexdump limit 1);
UPDATE users
SET image=
(
SELECT decode(hex, 'hex')
FROM hexdump LIMIT 1
)
WHERE id=15489 ;
" | psql mydatabase