Como posso escrever um procedimento armazenado que importa dados de um arquivo CSV e preenche a tabela?
Como posso escrever um procedimento armazenado que importa dados de um arquivo CSV e preenche a tabela?
Respostas:
Dê uma olhada neste pequeno artigo .
Solução parafraseada aqui:
Crie sua tabela:
CREATE TABLE zip_codes
(ZIP char(5), LATITUDE double precision, LONGITUDE double precision,
CITY varchar, STATE char(2), COUNTY varchar, ZIP_CLASS varchar);
Copie dados do seu arquivo CSV para a tabela:
COPY zip_codes FROM '/path/to/csv/ZIP_CODES.txt' WITH (FORMAT csv);
COPY zip_codes FROM '/path/to/csv/ZIP_CODES.txt' DELIMITER ',' CSV HEADER;
postgresql.org/docs/9.1/static/sql-copy.html
Se você não tem permissão para usar COPY
(que funciona no servidor db), poderá usá-lo \copy
(que funciona no cliente db). Usando o mesmo exemplo que Bozhidar Batsov:
Crie sua tabela:
CREATE TABLE zip_codes
(ZIP char(5), LATITUDE double precision, LONGITUDE double precision,
CITY varchar, STATE char(2), COUNTY varchar, ZIP_CLASS varchar);
Copie dados do seu arquivo CSV para a tabela:
\copy zip_codes FROM '/path/to/csv/ZIP_CODES.txt' DELIMITER ',' CSV
Você também pode especificar as colunas para ler:
\copy zip_codes(ZIP,CITY,STATE) FROM '/path/to/csv/ZIP_CODES.txt' DELIMITER ',' CSV
Consulte a documentação para COPY :
Não confunda COPY com a instrução psql \ copy. \ copy chama COPY FROM STDIN ou COPY TO STDOUT e, em seguida, busca / armazena os dados em um arquivo acessível ao cliente psql. Portanto, a acessibilidade do arquivo e os direitos de acesso dependem do cliente e não do servidor quando \ copy é usado.
e observe:
Para colunas de identidade, o comando COPY FROM sempre gravará os valores da coluna fornecidos nos dados de entrada, como a opção INSERIR OVERRIDING SYSTEM VALUE.
COPY
e \copy
é muito mais do que apenas permissões, e você não pode simplesmente adicionar um `` para fazê-lo funcionar magicamente. Veja a descrição (no contexto da exportação) aqui: stackoverflow.com/a/1517692/157957
Uma maneira rápida de fazer isso é com a biblioteca pandas Python (a versão 0.15 ou superior funciona melhor). Isso tratará da criação das colunas para você - embora, obviamente, as escolhas feitas para os tipos de dados possam não ser o que você deseja. Se isso não der certo, você sempre poderá usar o código 'create table' gerado como modelo.
Aqui está um exemplo simples:
import pandas as pd
df = pd.read_csv('mypath.csv')
df.columns = [c.lower() for c in df.columns] #postgres doesn't like capitals or spaces
from sqlalchemy import create_engine
engine = create_engine('postgresql://username:password@localhost:5432/dbname')
df.to_sql("my_table_name", engine)
E aqui está um código que mostra como definir várias opções:
# Set it so the raw sql output is logged
import logging
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
df.to_sql("my_table_name2",
engine,
if_exists="append", #options are ‘fail’, ‘replace’, ‘append’, default ‘fail’
index=False, #Do not output the index of the dataframe
dtype={'col1': sqlalchemy.types.NUMERIC,
'col2': sqlalchemy.types.String}) #Datatypes should be [sqlalchemy types][1]
if_exists
parâmetro pode ser configurado para substituir ou acrescentar a uma tabela existente, por exemplo,df.to_sql("fhrs", engine, if_exists='replace')
df.to_sql()
é realmente lento, você pode usar d6tstack.utils.pd_to_psql()
a partir d6tstack ver comparação de desempenho
Você também pode usar o pgAdmin, que oferece uma GUI para fazer a importação. Isso é mostrado neste tópico SO . A vantagem de usar o pgAdmin é que ele também funciona para bancos de dados remotos.
Assim como as soluções anteriores, você precisaria já ter sua tabela no banco de dados. Cada pessoa tem sua própria solução, mas o que eu costumo fazer é abrir o CSV no Excel, copiar os cabeçalhos, colar especial com transposição em uma planilha diferente, colocar o tipo de dados correspondente na próxima coluna e copiar e colar em um editor de texto juntamente com a consulta de criação de tabela SQL apropriada, da seguinte maneira:
CREATE TABLE my_table (
/*paste data from Excel here for example ... */
col_1 bigint,
col_2 bigint,
/* ... */
col_n bigint
)
A maioria das outras soluções aqui exige que você crie a tabela antecipadamente / manualmente. Isso pode não ser prático em alguns casos (por exemplo, se você tiver muitas colunas na tabela de destino). Portanto, a abordagem abaixo pode ser útil.
Fornecendo o caminho e a contagem de colunas do seu arquivo csv, você pode usar a seguinte função para carregar sua tabela em uma tabela temporária denominada como target_table
:
Presume-se que a linha superior tenha os nomes das colunas.
create or replace function data.load_csv_file
(
target_table text,
csv_path text,
col_count integer
)
returns void as $$
declare
iter integer; -- dummy integer to iterate columns with
col text; -- variable to keep the column name at each iteration
col_first text; -- first column name, e.g., top left corner on a csv file or spreadsheet
begin
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_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
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;
public
)
Como Paulo mencionou, a importação funciona no pgAdmin:
clique com o botão direito na tabela -> importar
selecione o arquivo local, formato e codificação
aqui está uma captura de tela alemã da pgAdmin GUI:
coisa semelhante que você pode fazer com o DbVisualizer (eu tenho uma licença, não tenho certeza da versão gratuita)
clique com o botão direito do mouse em uma tabela -> Importar Dados da Tabela ...
crie uma tabela primeiro
Em seguida, use o comando copy para copiar os detalhes da tabela:
copiar table_name (C1, C2, C3 ....)
do 'caminho para o arquivo csv' delimitador ',' cabeçalho csv;
obrigado
Use este código SQL
copy table_name(atribute1,attribute2,attribute3...)
from 'E:\test.csv' delimiter ',' csv header
a palavra-chave do cabeçalho informa ao DBMS que o arquivo csv possui um cabeçalho com atributos
para mais informações, visite http://www.postgresqltutorial.com/import-csv-file-into-posgresql-table/
Experiência pessoal com o PostgreSQL, ainda esperando por um caminho mais rápido.
1. Crie o esqueleto da tabela primeiro se o arquivo estiver armazenado localmente:
drop table if exists ur_table;
CREATE TABLE ur_table
(
id serial NOT NULL,
log_id numeric,
proc_code numeric,
date timestamp,
qty int,
name varchar,
price money
);
COPY
ur_table(id, log_id, proc_code, date, qty, name, price)
FROM '\path\xxx.csv' DELIMITER ',' CSV HEADER;
2. Quando o \ path \ xxx.csv estiver no servidor, o postgreSQL não tem permissão para acessar o servidor, você precisará importar o arquivo .csv através da funcionalidade incorporada no pgAdmin.
Clique com o botão direito do mouse no nome da tabela, escolha importar.
Se você ainda tiver problemas, consulte este tutorial. http://www.postgresqltutorial.com/import-csv-file-into-posgresql-table/
Como importar dados do arquivo CSV para uma tabela do PostgreSQL?
passos:
Precisa conectar o banco de dados postgresql no terminal
psql -U postgres -h localhost
Precisa criar banco de dados
create database mydb;
Precisa criar usuário
create user siva with password 'mypass';
Conectar-se ao banco de dados
\c mydb;
Precisa criar esquema
create schema trip;
Precisa criar tabela
create table trip.test(VendorID int,passenger_count int,trip_distance decimal,RatecodeID int,store_and_fwd_flag varchar,PULocationID int,DOLocationID int,payment_type decimal,fare_amount decimal,extra decimal,mta_tax decimal,tip_amount decimal,tolls_amount int,improvement_surcharge decimal,total_amount
);
Importar dados do arquivo csv para o postgresql
COPY trip.test(VendorID int,passenger_count int,trip_distance decimal,RatecodeID int,store_and_fwd_flag varchar,PULocationID int,DOLocationID int,payment_type decimal,fare_amount decimal,extra decimal,mta_tax decimal,tip_amount decimal,tolls_amount int,improvement_surcharge decimal,total_amount) FROM '/home/Documents/trip.csv' DELIMITER ',' CSV HEADER;
Encontre os dados da tabela fornecidos
select * from trip.test;
IMHO, a maneira mais conveniente é seguir " Importar dados CSV para o postgresql, da maneira mais confortável ;-) ", usando csvsql do csvkit , que é um pacote python instalável via pip.
No Python, você pode usar este código para criação automática de tabela do PostgreSQL com nomes de colunas:
import pandas, csv
from io import StringIO
from sqlalchemy import create_engine
def psql_insert_copy(table, conn, keys, data_iter):
dbapi_conn = conn.connection
with dbapi_conn.cursor() as cur:
s_buf = StringIO()
writer = csv.writer(s_buf)
writer.writerows(data_iter)
s_buf.seek(0)
columns = ', '.join('"{}"'.format(k) for k in keys)
if table.schema:
table_name = '{}.{}'.format(table.schema, table.name)
else:
table_name = table.name
sql = 'COPY {} ({}) FROM STDIN WITH CSV'.format(table_name, columns)
cur.copy_expert(sql=sql, file=s_buf)
engine = create_engine('postgresql://user:password@localhost:5432/my_db')
df = pandas.read_csv("my.csv")
df.to_sql('my_table', engine, schema='my_schema', method=psql_insert_copy)
Também é relativamente rápido, posso importar mais de 3,3 milhões de linhas em cerca de 4 minutos.
Se você precisar de um mecanismo simples para importar de texto / analisar CSV multilinhas, poderá usar:
CREATE TABLE t -- OR INSERT INTO tab(col_names)
AS
SELECT
t.f[1] AS col1
,t.f[2]::int AS col2
,t.f[3]::date AS col3
,t.f[4] AS col4
FROM (
SELECT regexp_split_to_array(l, ',') AS f
FROM regexp_split_to_table(
$$a,1,2016-01-01,bbb
c,2,2018-01-01,ddd
e,3,2019-01-01,eee$$, '\n') AS l) t;
O DBeaver Community Edition (dbeaver.io) facilita a conexão com um banco de dados e depois importa um arquivo CSV para upload para um banco de dados PostgreSQL. Também facilita a emissão de consultas, a recuperação de dados e o download de conjuntos de resultados para CSV, JSON, SQL ou outros formatos de dados comuns.
É uma ferramenta de banco de dados multi-plataforma FOSS para programadores, DBAs e analistas de SQL que suporta todos os bancos de dados populares: MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Hive, Presto, etc. É um concorrente viável do FOSS para o TOAD para Postgres, o TOAD para SQL Server ou o Toad para Oracle.
Não tenho afiliação com o DBeaver. Adoro o preço (GRATUITO!) E a funcionalidade completa, mas desejo que eles abram mais esse aplicativo DBeaver / Eclipse e facilitem a adição de widgets de análise ao DBeaver / Eclipse, em vez de exigir que os usuários paguem apenas US $ 199 por assinatura anual para criar gráficos e tabelas diretamente dentro do aplicativo. Minhas habilidades de codificação Java estão enferrujadas e não me apetece levar semanas para reaprender a criar widgets do Eclipse (apenas para descobrir que o DBeaver provavelmente desativou a capacidade de adicionar widgets de terceiros ao DBeaver Community Edition.)
Os usuários avançados do DBeaver, que são desenvolvedores de Java, podem fornecer algumas dicas sobre as etapas para criar widgets de análise para adicionar ao Community Edition do DBeaver?
Crie a tabela e tenha colunas necessárias que são usadas para criar a tabela no arquivo csv.
Abra o postgres e clique com o botão direito na tabela de destino que você deseja carregar e selecione importar e Atualize as seguintes etapas na seção de opções de arquivo
Agora procure seu arquivo no nome do arquivo
Selecione csv no formato
Codificação como ISO_8859_5
Agora vá para Misc. opções e verifique o cabeçalho e clique em importar.
Criei uma pequena ferramenta que importa csv
arquivos para o PostgreSQL super fácil, apenas um comando e ele criará e preencherá as tabelas, infelizmente, no momento todos os campos criados automaticamente usam o tipo TEXT
csv2pg users.csv -d ";" -H 192.168.99.100 -U postgres -B mydatabase
A ferramenta pode ser encontrada em https://github.com/eduardonunesp/csv2pg
psql -h 192.168.99.100 -U postgres mydatabase -c "COPY users FROM 'users.csv' DELIMITER ';' CSV"
? Eu acho que a parte onde ele cria a tabela é bom, mas uma vez que cada campo é um texto que não é super útil