Question

Cette question ne concerne pas bytea c. Oid c. Blobs c. Gros objets, etc.

J'ai une table contenant un champ integer clé primaire et un champ de bytea. Je voudrais saisir des données dans le champ bytea. Cela peut, sans doute, être fait par l'une des langues de PL/, et je peux regarder en faire avec PL/Python à l'avenir.

Comme je suis toujours tester et expérimenter, je voudrais simplement d'insérer des données à partir d'un fichier (sur le serveur) en utilisant des instructions SQL « standard ». Je suis conscient que seuls les administrateurs avec l'autorisation d'écriture sur le serveur serait en mesure d'insérer des données dans la façon dont je voudrais. Je ne suis pas inquiet à ce sujet à ce stade que les utilisateurs ne seraient pas insérer des données de bytea à l'heure actuelle. J'ai cherché les différents sites StackExchange, les Archives PostgreSQL et l'Internet en général, mais n'ont pas été en mesure de trouver une réponse.

Modifier Cette question similaire de 2005 reste sans réponse.

Résolu: Les détails fournis sur le site psycopg à condition que la base d'une solution que je l'ai écrit en Python. Il peut également être possible d'insérer des données binaires dans une colonne de bytea en utilisant PL/Python. Je ne sais pas si cela est possible en utilisant SQL « pure ».

Était-ce utile?

La solution

comme super-utilisateur:

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 a été introduit en 9.4 ainsi pour les versions plus anciennes que vous aurait besoin:

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

alors:

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

Autres conseils

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

Par exemple,

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

Manuel

Cette solution est pas tout à fait efficace en termes d'exécution, mais il est trivialement facile par rapport à faire vos propres en-têtes pour COPY BINARY. En outre, il ne nécessite pas de bibliothèques ou langages de script en dehors de bash.

Tout d'abord, convertir le fichier dans un hexdump, doublant la taille du fichier. xxd -p nous obtient assez proche, mais il jette dans certains ennuyeux que les nouvelles lignes que nous devons prendre soin de:

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

Ensuite, importer les données dans PostgreSQL comme un très grand champ text. Ce type peut contenir jusqu'à un Go par valeur du champ, nous devons donc être acceptable pour la plupart des cas:

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

Maintenant que nos données est une chaîne hexagonale large à titre gratuit, nous utilisons la decode de PostgresQL pour l'obtenir dans un type de bytea:

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

Le réponse avec xxd est agréable et, pour les petits fichiers, très rapide. Ci-dessous un exemple de script que j'utilise.

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

Utilisez le Postgres fonction BINARY COPY. Ceci est largement équivalent à Oracle de tables externes .

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top