Экспорт только имен столбцов из таблицы postgres в CSV

Я новичок в PostgreSQL, но до сих пор сталкивался только с учебниками о том, как экспортировать целые таблицы с заголовками .csv. Я хотел бы экспортировать только имена полей.

Как написать запрос, чтобы экспортировать только имена столбцов таблицы xв a .csv ?

3 ответа

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

    или

    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;
    
  2. Вы должны знать, что из psqlконсоли вы можете запросить полезную информацию о структуре таблицы с \dпомощью команды.

    Конечно, я понял, что вам нужно получить эту информацию с помощью SQL-запроса, выполненного из вашего приложения.

    Но, если вы вызываете psqlС -E(или--echo-hidden), то после ввода \d some table(или любой другой консольной команды) он также выведет запрос (или запросы), используемый для получения этой информации. Что очень полезно в подобных случаях.

    Например:

    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...]
    

    Теперь, комбинируя третий запрос с первым, легко построить именно то, что вы хотите:

    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;
    

    На самом деле, вы также можете изменить WHERE c.relname ~ '^(foo)$'с WHERE c.relname = 'foo'too. За исключением тех случаев, когда требуется сопоставить имена таблиц по регулярному выражению. Что, я думаю, не ваш случай.

  3. другой метод, используя psql из командной строки, так что привилегии суперпользователя не требуются

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

    Возвращает только имена столбцов в списке, разделенном запятыми:

    $ more tmp/foo.csv
    id,name,date,status...