如何编写从CSV文件导入数据并填充表的存储过程?


当前回答

您可以创建一个Bash文件import.sh(您的CSV格式是一个制表符分隔符):

#!/usr/bin/env bash

USER="test"
DB="postgres"
TBALE_NAME="user"
CSV_DIR="$(pwd)/csv"
FILE_NAME="user.txt"

echo $(psql -d $DB -U $USER  -c "\copy $TBALE_NAME from '$CSV_DIR/$FILE_NAME' DELIMITER E'\t' csv" 2>&1 |tee /dev/tty)

然后运行这个脚本。

其他回答

如何将CSV文件数据导入PostgreSQL表

步骤:

Need to connect a PostgreSQL database in the terminal psql -U postgres -h localhost Need to create a database create database mydb; Need to create a user create user siva with password 'mypass'; Connect with the database \c mydb; Need to create a schema create schema trip; Need to create a table 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 ); Import csv file data to 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; Find the given table data select * from trip.test;

我创建了一个小工具,可以超级简单地将csv文件导入PostgreSQL。它只是一个命令,它将创建和填充表,但不幸的是,目前自动创建的所有字段都使用TEXT类型:

csv2pg users.csv -d ";" -H 192.168.99.100 -U postgres -B mydatabase

该工具可以在https://github.com/eduardonunesp/csv2pg上找到

这些都是很好的答案,但对我来说太复杂了。我只需要在postgreSQL中加载一个CSV文件,而不需要先创建一个表。

这是我的方法:

import pandas as pd
import os
import psycopg2 as pg
from sqlalchemy  import create_engine

使用环境变量获取密码

password = os.environ.get('PSW')

创建引擎

engine = create_engine(f"postgresql+psycopg2://postgres:{password}@localhost:5432/postgres")

发动机需求分解:

Engine = create_engine(dialect+驱动程序://用户名:password@host:端口/数据库)

分解

Postgresql +psycopg2 =方言+驱动程序 Postgres =用户名 Password =来自环境变量的密码。如果需要,可以输入密码,但不建议输入 Localhost = host 5432 = port Postgres =数据库

获取您的CSV文件路径,我不得不使用编码方面。原因可以在这里找到

data = pd.read_csv(r"path, encoding= 'unicode_escape')

发送数据到Postgress SQL:

data.to_sql('test', engine, if_exists='replace')

分解

Test =你想要的表名 引擎=上面创建的引擎。也就是我们的联系 if_exists =将替换旧表。请谨慎使用。

在一起:

import pandas as pd
import os
import psycopg2 as pg
from sqlalchemy  import create_engine

password = os.environ.get('PSW')

engine = create_engine(f"postgresql+psycopg2://postgres:{password}@localhost:5432/postgres")

data = pd.read_csv(r"path, encoding= 'unicode_escape')
data.to_sql('test', engine, if_exists='replace')

如果文件不是很大,可以使用Pandas库。

在Pandas数据框架上使用iter时要小心。我这样做是为了证明这种可能性。当从数据帧复制到SQL表时,也可以考虑使用pd.Dataframe.to_sql()函数。

假设你已经创建了你想要的表,你可以:

import psycopg2
import pandas as pd
data=pd.read_csv(r'path\to\file.csv', delimiter=' ')

#prepare your data and keep only relevant columns

data.drop(['col2', 'col4','col5'], axis=1, inplace=True)
data.dropna(inplace=True)
print(data.iloc[:3])


conn=psycopg2.connect("dbname=db user=postgres password=password")
cur=conn.cursor()

for index,row in data.iterrows():
      cur.execute('''insert into table (col1,col3,col6)
    VALUES (%s,%s,%s)''', (row['col1'], row['col3'], row['col6'])

cur.close()
conn.commit()

conn.close()
print('\n db connection closed.')

一种快速的方法是使用Python Pandas库(0.15或更高版本最好)。这将为您处理创建列的问题——尽管它为数据类型所做的选择可能不是您想要的。如果它不能完全做到你想要的,你总是可以使用生成为模板的“创建表”代码。

这里有一个简单的例子:

import pandas as pd
df = pd.read_csv('mypath.csv')
df.columns = [c.lower() for c in df.columns] # PostgreSQL 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)

下面是一些代码,告诉你如何设置各种选项:

# 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