Frage

In dieser Frage geht es nicht um Bytea v. Oid v. Blobs v. Große Objekte usw.

Ich habe eine Tabelle mit einem Primärschlüssel integer Feld und a bytea aufstellen. Ich möchte Daten in die eingeben bytea aufstellen. Dies kann vermutlich von einem der von einem der von erledigt werden PL/ Sprachen, und ich kann mir das ansehen PL/Python in der Zukunft.

Während ich noch teste und experimentiere, möchte ich einfach Daten aus einer Datei (auf dem Server) mit "Standard" -S -SQL -Anweisungen einfügen. Ich bin mir bewusst, dass nur Administratoren mit Schreibberechtigung auf dem Server Daten so einfügen könnten, wie ich es möchte. Ich bin in dieser Phase nicht besorgt darüber, da die Benutzer nicht einfügen würden bytea Daten derzeit. Ich habe die verschiedenen Stackexchange -Websites, die PostgreSQL -Archive und das Internet im Allgemeinen durchsucht, konnten aber keine Antwort finden.

Bearbeiten: Dies Die Diskussion von 2008 impliziert, dass das, was ich tun möchte, nicht möglich ist. Wie bist bytea Felder dann verwendet dann?

Bearbeiten: Dies Eine ähnliche Frage aus dem Jahr 2005 bleibt unbeantwortet.

Gelöst: Die angegebenen Details hier auf der psycopg Die Website bildete die Grundlage für eine Lösung, die ich in Python geschrieben habe. Es kann auch möglich sein, Binärdaten in a einzufügen bytea Spalte verwendet PL/Python. Ich weiß nicht, ob dies mit "reinem" SQL möglich ist.

War es hilfreich?

Lösung

als Superuser:

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 wurde in 9.4 eingeführt, also für ältere Versionen, die Sie brauchen würden:

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;$$;

dann:

insert into my_table(bytea_data) select bytea_import('/my/file.name');

Andere Tipps

Verwenden pg_read_file('location_of file')::bytea.

Zum Beispiel,

create table test(id int, image bytea);
insert into test values (1, pg_read_file('/home/xyz')::bytea);

Handbuch

Diese Lösung ist in Bezug auf die Laufzeit nicht gerade effizient, aber sie ist im Vergleich zu Ihren eigenen Headern für eindeutig einfach COPY BINARY. Darüber hinaus sind keine Bibliotheken oder Skriptsprachen außerhalb von Bash erforderlich.

Konvertieren Sie zuerst die Datei in einen Hexdump, wodurch die Größe der Datei verdoppelt wird. xxd -p Bringt uns ziemlich nah, aber es gibt einige nervige Neulinge ein, um die wir uns kümmern müssen:

xxd -p /path/file.bin | tr -d '\n' > /path/file.hex

Importieren Sie die Daten als nächstes in PostgreSQL als sehr große text aufstellen. Dieser Typ hält bis zu einem GB pro Feldwert, daher sollten wir für die meisten Zwecke in Ordnung sein:

CREATE TABLE hexdump (hex text); COPY hexdump FROM '/path/file.hex';

Jetzt, da unsere Daten eine unentgeltlich große Hex -Zeichenfolge sind, verwenden wir Postgresqls decode um es in eine zu bringen bytea Typ:

CREATE TABLE bindump AS SELECT decode(hex, 'hex') FROM hexdump;

Das Antwort mit xxd ist schön und für kleine Dateien sehr schnell. Unten ist ein Beispielskript, das ich verwende.

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

Verwenden Sie die Postgres Binär kopieren Funktion. Dies entspricht weitgehend der Oracle's externe Tische.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top