Как скопировать из CSV-файла в таблицу PostgreSQL с заголовками в CSV-файле?
Я хочу, чтобы скопировать CSV-файла в таблицу базы данных Postgres. В этой таблице около 100 столбцов, поэтому я не хочу их переписывать, если мне это не нужно.
Я использую copy table from 'table.csv' delimiter ',' csv; команда, но без таблицы, созданной я получаю ERROR: relation "table" does not exist. Если я добавляю пустую таблицу, я не получаю ошибки, но ничего не происходит. Я попробовал эту команду два или три раза, и не было никаких выходных данных или сообщений, но таблица не была обновлена, когда я проверил ее через PGAdmin.
есть ли способ импортировать a таблица с заголовками как я пытаюсь сделать?
4 ответов:
это сработало. В первой строке были имена столбцов.
COPY wheat FROM 'wheat_crop_data.csv' DELIMITER ';' CSV HEADER
с библиотекой Python
pandas, вы можете легко создавать имена столбцов и выводить типы данных из файла csv.from sqlalchemy import create_engine import pandas as pd engine = create_engine('postgresql://user:pass@localhost/db_name') df = pd.read_csv('/path/to/csv_file') df.to_sql('pandas_db', engine)The
if_existsпараметр может быть установлен для замены или добавления к существующей таблице, напримерdf.to_sql('pandas_db', engine, if_exists='replace'). Это работает и для дополнительных типов входных файлов, docs здесь и здесь.
альтернатива терминалом без разрешения
The PG документация в NOTES скажи
путь будет интерпретироваться относительно рабочего каталога серверного процесса (обычно каталога данных кластера), а не рабочего каталога клиента.
так, gerally, используя
psqlили любой клиент, даже на локальном сервере, у вас есть проблемы ... И, если вы выражаете команду копирования для других пользователей, например. на Github README, у читателя будут проблемы ...единственный способ выразить относительный путь с разрешения клиента использует STDIN,
когда указан STDIN или STDOUT, данные передаются через соединение между клиентом и сервером.
как вспомнил тут:
psql -h remotehost -d remote_mydb -U myuser -c \ "copy mytable (column1, column2) from STDIN with delimiter as ','" \ < ./relative_path/file.csv
Я использую эту функцию в течение некоторого времени без проблем. Вам просто нужно указать количество столбцов, которые есть в csv-файле, и он возьмет имена заголовков из первой строки и создаст таблицу для вас:
create or replace function data.load_csv_file ( target_table text, -- name of the table that will be created csv_file_path text, col_count integer ) returns void as $$ declare iter integer; -- dummy integer to iterate columns with col text; -- to keep column names in each iteration col_first text; -- first column name, e.g., top left corner on a csv file or spreadsheet begin set schema 'data'; create table temp_table (); -- add just enough number of columns for iter in 1..col_count loop execute format ('alter table temp_table add column col_%s text;', iter); end loop; -- copy the data from csv file execute format ('copy temp_table from %L with delimiter '','' quote ''"'' csv ', csv_file_path); iter := 1; col_first := (select col_1 from temp_table limit 1); -- update the column names based on the first row which has the column names for col in execute format ('select unnest(string_to_array(trim(temp_table::text, ''()''), '','')) from temp_table where col_1 = %L', col_first) loop execute format ('alter table temp_table rename column col_%s to %s', iter, col); iter := iter + 1; end loop; -- delete the columns row // using quote_ident or %I does not work here!? execute format ('delete from temp_table where %s = %L', col_first, col_first); -- change the temp table name to the name given as parameter, if not blank if length (target_table) > 0 then execute format ('alter table temp_table rename to %I', target_table); end if; end; $$ language plpgsql;
Comments