(ファイル)データをPostgreSQL BYTEA列に挿入する方法は?
-
16-10-2019 - |
質問
この質問は、Byteav。Oidv。Blobsv。GrageObjectsなどに関するものではありません。
主キーを含むテーブルがあります integer
フィールドとa bytea
分野。にデータを入力したいと思います bytea
分野。これは、おそらく、 PL/
言語、そして私はこれを行うことを検討するかもしれません PL/Python
将来。
私はまだテストと実験を行っているので、「標準」SQLステートメントを使用して(サーバー上)ファイルからデータを挿入したいだけです。サーバーに書き込み許可を持つ管理者のみが、私が望む方法でデータを挿入できることを知っています。ユーザーが挿入していないので、私はこの段階でそれを心配していません bytea
現在のデータ。さまざまなstackexchangeサイト、postgreSQLアーカイブ、インターネットを一般的に検索しましたが、答えを見つけることができませんでした。
編集: これ 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
. 。さらに、Bash以外のライブラリやスクリプト言語は必要ありません。
まず、ファイルをヘックスダンプに変換し、ファイルのサイズを2倍にします。 xxd -p
私たちをかなり近づけますが、私たちが世話をしなければならないいくつかの迷惑なニューラインを投げます:
xxd -p /path/file.bin | tr -d '\n' > /path/file.hex
次に、PostgreSQLのデータを非常に大きなものとしてインポートします text
分野。このタイプは、フィールド値ごとに最大1 GBを保持しているため、ほとんどの目的では問題ありません。
CREATE TABLE hexdump (hex text); COPY hexdump FROM '/path/file.hex';
私たちのデータが無償で大きな16進ストリングになったので、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
Postgresを使用します バイナリをコピーします 働き。これは、Oracleのものとほぼ同等です 外部テーブル.