Pregunta

Esta pregunta no es sobre bytea v. V OID. Manchas v. Objetos de gran tamaño, etc.

Tengo una tabla que contiene un campo integer clave principal y un campo bytea. Me gustaría introducir datos en el campo bytea. Esta lata, presumiblemente, ser realizado por uno de los idiomas PL/, y puede mirar en hacer esto con PL/Python en el futuro.

Como Todavía estoy probando y experimentando, Quisiera simplemente para insertar datos de un archivo (en el servidor), utilizando sentencias SQL "estándar". Soy consciente de que sólo los administradores con permiso de escritura en el servidor serían capaces de insertar datos en la forma en que me gustaría. No estoy preocupado por eso en esta etapa ya que los usuarios no serían la inserción de datos bytea en la actualidad. He buscado en los diversos sitios Stackexchange, el Archivo de PostgreSQL y el Internet en general, pero no han sido capaces de encontrar una respuesta.

Editar: Esta discusión de 2008 implica que lo que quiero hacer no es posible. ¿Cómo se usan los campos bytea entonces?

Editar Este pregunta similar de 2005 sigue sin respuesta.

Resuelto: Los datos facilitados aquí en el sitio web psycopg servido de base para una solución que he escrito en Python. También puede ser posible insertar datos binarios en una columna bytea usando PL/Python. No sé si esto es posible utilizando SQL "pura".

¿Fue útil?

Solución

como superusuario:

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 se introdujo en 9.4 por lo que para las versiones anteriores necesitaría:

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

a continuación:

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

Otros consejos

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

Por ejemplo,

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

manual

Esta solución no es exactamente eficiente en términos de tiempo de ejecución, pero es trivialmente fácil en comparación a hacer sus propias cabeceras de COPY BINARY. Además, no requiere ninguna biblioteca o lenguajes de programación fuera de fiesta.

En primer lugar, convertir el archivo en un hexdump, duplicando el tamaño del archivo. xxd -p nos pone muy cerca, pero los tiros en algunos saltos de línea molestos que tenemos que tener cuidado de:

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

A continuación, importar los datos en PostgreSQL como un campo text muy grande. Este tipo puede contener hasta un GB por valor de campo, por lo que debemos estar bien para la mayoría de los propósitos:

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

Ahora que nuestros datos es una cadena hexadecimal gratuitamente grande, utilizamos decode de PostgreSQL para entrar en un tipo bytea:

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

con xxd es agradable y, para archivos pequeños, muy rápido. A continuación se muestra un script de ejemplo que estoy 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

Función Uso del Postgres copia binaria . Esto es más o menos equivalente a la de Oracle tablas externas .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a dba.stackexchange
scroll top