Exportar filas específicas de una tabla PostgreSQL como INSERTAR script SQL


Tengo un esquema de base de datos llamado: nyummy y una tabla llamada cimory:

create table nyummy.cimory (
  id numeric(10,0) not null,
  name character varying(60) not null,
  city character varying(50) not null,
  CONSTRAINT cimory_pkey PRIMARY KEY (id)
);

Quiero exportar los datos de la tabla cimory como insert SQL script file. Sin embargo, solo quiero exportar registros/datos donde la ciudad es igual a 'tokio' (supongamos que los datos de la ciudad son todos en minúsculas).

¿Cómo hacerlo?

No importa si la solución está en herramientas GUI freeware o línea de comandos (aunque la solución de herramientas GUI es mejor). Había intentado pgAdmin III, pero no puedo encontrar una opción para hacer este.

Author: Erwin Brandstetter, 2012-10-10

9 answers

Cree una tabla con el conjunto que desea exportar y luego use la utilidad de línea de comandos pg_dump para exportar a un archivo:

create table export_table as 
select id, name, city
from nyummy.cimory
where city = 'tokio'
$ pg_dump --table=export_table --data-only --column-inserts my_database > data.sql

--column-inserts volcará como comandos de inserción con nombres de columna.

--data-only no volcar esquema.

Como se comenta a continuación, crear una vista en lugar de una tabla evitará la creación de la tabla siempre que sea necesaria una nueva exportación.

 209
Author: Clodoaldo Neto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-27 19:35:39

For a data-only export use COPY.
Obtienes un archivo con una fila de tabla por línea como texto sin formato (no comandos INSERT), es más pequeño y más rápido:

COPY (SELECT * FROM nyummy.cimory WHERE city = 'tokio') TO '/path/to/file.csv';

Importar lo mismo a otra tabla de la misma estructura en cualquier lugar con:

COPY other_tbl FROM '/path/to/file.csv';

COPY escribe y lee archivos locales al servidor, a diferencia de programas cliente como pg_dump o psqlque leen y escriben archivos locales al cliente. Si ambos se ejecutan en el mismo máquina, no importa mucho, pero sí para conexiones remotas.

También está el \copy comando de psql que:

Realiza una copia de frontend (cliente). Esta es una operación que ejecuta un SQL COPY, pero en lugar de leer o escribir el servidor archivo especificado, psql lee o escribe el archivo y enruta los datos entre el servidor y el sistema de archivos local. Esto significa que el archivo la accesibilidad y los privilegios son los del usuario local, no el servidor, y no se requieren privilegios de superusuario SQL.

 134
Author: Erwin Brandstetter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-28 21:43:16

Esta es una forma fácil y rápida de exportar una tabla a un script con pgAdmin manualmente sin instalaciones adicionales :

  1. Haga clic derecho en la tabla de destino y seleccione "Copia de seguridad".
  2. Seleccione una ruta de archivo para almacenar la copia de seguridad. Como Formato elegir "Llano".
  3. Abra la pestaña "Opciones de volcado #2" en la parte inferior y marque "Usar inserciones de columna".
  4. Haga clic en el botón de copia de seguridad.
  5. Si abre el archivo resultante con un lector de texto (por ejemplo, notepad++), obtenga un script para crear toda la tabla. Desde allí, simplemente puede copiar las instrucciones INSERT generadas.

Este método también funciona con la técnica de hacer una export_table como se demuestra en la respuesta de @Clodoaldo Neto.

Haga clic derecho en la tabla de destino y elija " Copia de seguridad"

Elija una ruta de destino y cambie el formato a " Plano"

Abra la pestaña "Opciones de volcado # 2" en la parte inferior y marque " Usar inserciones de columna"

Puede copiar las instrucciones INSERT desde allí.

 18
Author: Andi R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-15 20:13:04

SQL Workbench tiene tal característica.

Después de ejecutar una consulta, haga clic derecho en los resultados de la consulta y elija "Copiar datos como SQL > Insertar SQL"

 8
Author: machinery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-27 12:58:12

Para mi caso de uso pude simplemente canalizar a grep.

pg_dump -U user_name --data-only --column-inserts -t nyummy.cimory | grep "tokyo" > tokyo.sql
 5
Author: M.Vanderlee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-25 15:38:41

Puede hacer una vista de la tabla con registros específicos y luego volcar el archivo sql

CREATE VIEW foo AS
SELECT id,name,city FROM nyummy.cimory WHERE city = 'tokyo'
 2
Author: Giorgi Peikrishvili,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-10 09:04:19

Acabo de preñar un procedimiento rápido para hacer esto. Solo funciona para una sola fila, así que creo una vista temporal que solo selecciona la fila que quiero, y luego reemplace el pg_temp.temp_view con la tabla real en la que quiero insertar.

CREATE OR REPLACE FUNCTION dv_util.gen_insert_statement(IN p_schema text, IN p_table text)
  RETURNS text AS
$BODY$
DECLARE
    selquery text; 
    valquery text; 
    selvalue text; 
    colvalue text; 
    colrec record;
BEGIN

    selquery := 'INSERT INTO ' ||  quote_ident(p_schema) || '.' || quote_ident(p_table);

    selquery := selquery || '(';

    valquery := ' VALUES (';
    FOR colrec IN SELECT table_schema, table_name, column_name, data_type
                  FROM information_schema.columns 
                  WHERE table_name = p_table and table_schema = p_schema 
                  ORDER BY ordinal_position 
    LOOP
      selquery := selquery || quote_ident(colrec.column_name) || ',';

      selvalue := 
        'SELECT CASE WHEN ' || quote_ident(colrec.column_name) || ' IS NULL' || 
                   ' THEN ''NULL''' || 
                   ' ELSE '''' || quote_literal('|| quote_ident(colrec.column_name) || ')::text || ''''' || 
                   ' END' || 
        ' FROM '||quote_ident(p_schema)||'.'||quote_ident(p_table);
      EXECUTE selvalue INTO colvalue;
      valquery := valquery || colvalue || ',';
    END LOOP;
    -- Replace the last , with a )
    selquery := substring(selquery,1,length(selquery)-1) || ')';
    valquery := substring(valquery,1,length(valquery)-1) || ')';

    selquery := selquery || valquery;

RETURN selquery;
END
$BODY$
  LANGUAGE plpgsql VOLATILE;

Invocado así:

SELECT distinct dv_util.gen_insert_statement('pg_temp_' || sess_id::text,'my_data') 
from pg_stat_activity 
where procpid = pg_backend_pid()

No he probado esto contra ataques de inyección, por favor hágamelo saber si la llamada quote_literal no es suficiente para eso.

También solo funciona para columnas que pueden ser simplemente lanzadas a:: text y atrás nuevo.

También esto es para Greenplum, pero no puedo pensar en una razón por la que no funcionaría en Postgres, CMIIW.

 0
Author: PhilHibbs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-17 13:53:06

Traté de escribir un procedimiento haciendo eso, basado en los códigos @PhilHibbs, de una manera diferente. Por favor, echa un vistazo y prueba.

 CREATE OR REPLACE FUNCTION dump(IN p_schema text, IN p_table text, IN p_where text)
   RETURNS setof text AS
 $BODY$
 DECLARE
     dumpquery_0 text;
     dumpquery_1 text;
     selquery text;
     selvalue text;
     valrec record;
     colrec record;
 BEGIN

     -- ------ --
     -- GLOBAL --
     --   build base INSERT
     --   build SELECT array[ ... ]
     dumpquery_0 := 'INSERT INTO ' ||  quote_ident(p_schema) || '.' || quote_ident(p_table) || '(';
     selquery    := 'SELECT array[';

     <<label0>>
     FOR colrec IN SELECT table_schema, table_name, column_name, data_type
                   FROM information_schema.columns
                   WHERE table_name = p_table and table_schema = p_schema
                   ORDER BY ordinal_position
     LOOP
         dumpquery_0 := dumpquery_0 || quote_ident(colrec.column_name) || ',';
         selquery    := selquery    || 'CAST(' || quote_ident(colrec.column_name) || ' AS TEXT),';
     END LOOP label0;

     dumpquery_0 := substring(dumpquery_0 ,1,length(dumpquery_0)-1) || ')';
     dumpquery_0 := dumpquery_0 || ' VALUES (';
     selquery    := substring(selquery    ,1,length(selquery)-1)    || '] AS MYARRAY';
     selquery    := selquery    || ' FROM ' ||quote_ident(p_schema)||'.'||quote_ident(p_table);
     selquery    := selquery    || ' WHERE '||p_where;
     -- GLOBAL --
     -- ------ --

     -- ----------- --
     -- SELECT LOOP --
     --   execute SELECT built and loop on each row
     <<label1>>
     FOR valrec IN  EXECUTE  selquery
     LOOP
         dumpquery_1 := '';
         IF not found THEN
             EXIT ;
         END IF;

         -- ----------- --
         -- LOOP ARRAY (EACH FIELDS) --
         <<label2>>
         FOREACH selvalue in ARRAY valrec.MYARRAY
         LOOP
             IF selvalue IS NULL
             THEN selvalue := 'NULL';
             ELSE selvalue := quote_literal(selvalue);
             END IF;
             dumpquery_1 := dumpquery_1 || selvalue || ',';
         END LOOP label2;
         dumpquery_1 := substring(dumpquery_1 ,1,length(dumpquery_1)-1) || ');';
         -- LOOP ARRAY (EACH FIELD) --
         -- ----------- --

         -- debug: RETURN NEXT dumpquery_0 || dumpquery_1 || ' --' || selquery;
         -- debug: RETURN NEXT selquery;
         RETURN NEXT dumpquery_0 || dumpquery_1;

     END LOOP label1 ;
     -- SELECT LOOP --
     -- ----------- --

 RETURN ;
 END
 $BODY$
   LANGUAGE plpgsql VOLATILE;

Y luego:

-- for a range
SELECT dump('public', 'my_table','my_id between 123456 and 123459'); 
-- for the entire table
SELECT dump('public', 'my_table','true');

Probado en mi postgres 9.1, con una tabla con tipo de datos de campo mixto (texto, doble, int,marca de tiempo sin zona horaria, etc.).

Es por eso que el tipo de TEXTO FUNDIDO es necesario. Mi prueba se ejecuta correctamente durante aproximadamente 9M líneas, parece que falla justo antes de 18 minutos de ejecución.

Pd: He encontrado un equivalente para mysql en el WEB.

 0
Author: Vi Shen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-24 13:15:07

Ha intentado en pgadmin ejecutar la consulta con " EXECUTE QUERY WRITE RESULT TO FILE " opción

Solo exporta los datos, de lo contrario intenta como

pg_dump -t view_name DB_name > db.sql

- t opción utilizada para = = > Volcar solo tablas (o vistas o secuencias) tabla coincidente, refer

 -2
Author: solaimuruganv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-10 09:22:06