Domanda

Questa domanda non riguarda bytea v. OID v. Blob v. Oggetti di grandi dimensioni, ecc

Ho una tabella che contiene un campo integer chiave primaria e un campo bytea. Mi piacerebbe inserire i dati nel campo bytea. Questo può, presumibilmente, essere fatto da una delle lingue PL/, e posso guardare in questo modo con PL/Python in futuro.

Mentre sto ancora testando e sperimentando, vorrei semplicemente inserire i dati da un file (sul server) utilizzando le istruzioni SQL "standard". Sono consapevole del fatto che solo gli amministratori con i permessi di scrittura sul server sarebbe in grado di inserire i dati nel modo vorrei. Io non sono preoccupato per che in questa fase, gli utenti non sarebbero l'inserimento dei dati bytea attualmente. Ho cercato i vari siti StackExchange, l'Archivio di PostgreSQL e di Internet in generale, ma non sono stati in grado di trovare una risposta.

Modifica Questa discussione dal 2008 implica che ciò che voglio fare non è possibile. Come vengono utilizzati i campi bytea allora?

Modifica Questo domanda simile da 2005 rimane senza risposta.

Risolto: I dati forniti qui sul sito psycopg fornito la base per una soluzione che ho scritto in Python. Può anche essere possibile inserire dati binari in una colonna bytea utilizzando PL/Python. Non so se questo è possibile utilizzando SQL "puro".

È stato utile?

Soluzione

come superutente:

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 è stato introdotto in 9.4 così per le versioni precedenti voi avrebbe bisogno di:

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

quindi:

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

Altri suggerimenti

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

Ad esempio,

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

manuale

Questa soluzione non è esattamente efficiente in termini di tempo di esecuzione, ma è banalmente facile rispetto a fare le proprie intestazioni per COPY BINARY. Inoltre, non richiede librerie o linguaggi di scripting di fuori di bash.

In primo luogo, convertire il file in un hexdump, raddoppiando le dimensioni del file. xxd -p noi diventa piuttosto vicino, ma getta in alcune nuove righe fastidiosi che dobbiamo prendere cura di:

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

Avanti, importare i dati in PostgreSQL come un campo molto grande text. Questo tipo può contenere fino a un GB per ogni valore di campo, quindi dovremmo essere a posto per la maggior parte degli scopi:

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

Ora che i nostri dati è una grande gratuitamente stringa esadecimale, usiamo decode di PostgreSQL per farlo in un tipo bytea:

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

La risposta con xxd è bello e, per i file di piccole dimensioni, molto veloce. Di seguito è riportato uno script di esempio che sto usando.

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

Utilizzare la Postgres copia binaria funzione. Questo è grosso modo equivalenti a Oracle di tabelle esterne .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top