Ответ 1
Это сработало. В первой строке были имена столбцов.
COPY wheat FROM 'wheat_crop_data.csv' DELIMITER ';' CSV HEADER
Я хочу скопировать CSV файл в таблицу Postgres. В этой таблице около 100 столбцов, поэтому я не хочу их переписывать, если мне это не нужно.
Я использую команду \copy table from 'table.csv' delimiter ',' csv;
, но без созданной таблицы я получаю ERROR: relation "table" does not exist
. Если я добавлю пустую таблицу, я не получу ошибки, но ничего не произойдет. Я пробовал эту команду два или три раза, и не было никаких выходных или сообщений, но таблица не обновлялась, когда я проверил ее через PGAdmin.
Есть ли способ импортировать таблицу с включенными заголовками, как я пытаюсь сделать?
Это сработало. В первой строке были имена столбцов.
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:[email protected]/db_name')
df = pd.read_csv('/path/to/csv_file')
df.to_sql('pandas_db', engine)
Параметр if_exists
может быть установлен для замены или добавления в существующую таблицу, например. df.to_sql('pandas_db', engine, if_exists='replace')
. Это работает и для дополнительных типов входных файлов, docs здесь и здесь.
документация pg по ПРИМЕЧАНИЯм говорят
Путь будет интерпретироваться относительно рабочего каталога процесса сервера (обычно это каталог данных кластера), а не рабочего каталога клиента.
Итак, при использовании psql
или любого клиента, даже на локальном сервере, у вас есть проблемы... И, если вы выражаете команду COPY для других пользователей, например. в 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;