Soy nuevo en PostgreSQL, pero hasta ahora solo he encontrado tutoriales sobre cómo exportar tablas completas con encabezados a .csv. Me gustaría exportar solo nombres de campo.

¿Cómo escribiría una consulta para exportar solo los nombres de columna de la tabla x a un .csv?

1
the_darkside 28 dic. 2016 a las 09:33

3 respuestas

La mejor respuesta
 COPY (select * from table_name where false)  -- To return result without rows
 TO 'D:\File.csv' DELIMITER ',' CSV HEADER;

O

create temp table tmp (like table_name); -- To copy structure into a new temp table
COPY tmp  TO 'D:/File.csv' DELIMITER ',' CSV HEADER;
drop table tmp;
0
Vivek S. 28 dic. 2016 a las 06:56

Debe saber que desde la consola psql puede solicitar información útil sobre la estructura de la tabla con el comando \d.

Por supuesto, entendí que lo que necesita es recuperar esa información con una consulta SQL ejecutada desde su aplicación.

Pero, si llama a psql con -E (o --echo-hidden), luego de escribir \d some table (o cualquier otro comando de la consola) también generará la consulta (o consultas ) utilizado para obtener esa información. Lo cual es muy útil en casos como ese.

Por ejemplo:

test=> \d foo
********* QUERY **********
SELECT c.oid,
  n.nspname,
  c.relname
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname ~ '^(foo)$'
  AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 2, 3;
**************************

********* QUERY **********
SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, c.relhastriggers, c.relhasoids, '', c.reltablespace, CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, c.relp
ersistence, c.relreplident
FROM pg_catalog.pg_class c
 LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)
WHERE c.oid = '41967';
**************************

********* QUERY **********
SELECT a.attname,
  pg_catalog.format_type(a.atttypid, a.atttypmod),
  (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
   FROM pg_catalog.pg_attrdef d
   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),
  a.attnotnull, a.attnum,
  (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t
   WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation,
  NULL AS indexdef,
  NULL AS attfdwoptions
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = '41967' AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum;
**************************

[...more...]

Ahora, combinar la tercera consulta con la primera es fácil de construir justo lo que desea:

SELECT a.attname
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = (
    SELECT c.oid
    FROM pg_catalog.pg_class c
    WHERE c.relname ~ '^(foo)$'
)
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum;

De hecho, también puede cambiar WHERE c.relname ~ '^(foo)$' con WHERE c.relname = 'foo' también. Excepto si desea poder hacer coincidir los nombres de las tablas por expresión regular. Lo cual creo que no es tu caso.

0
bitifet 28 dic. 2016 a las 07:28

Otro método, usando psql desde la línea de comando, para que no se requieran privilegios de superusuario

psql -U user -d database -c "COPY (SELECT * FROM table WHERE FALSE) To STDOUT With CSV HEADER DELIMITER ',';" > tmp/foo.csv

Esto devuelve solo los nombres de columna, en una lista separada por comas:

$ more tmp/foo.csv
id,name,date,status...
0
toms 22 may. 2018 a las 21:42