簡體   English   中英

使用python將數據從csv復制到postgresql

[英]copy data from csv to postgresql using python

我在 Windows 7 64 位上。 我有一個 csv 文件“data.csv”。 我想通過 python 腳本將數據導入 postgresql 表“temp_unicommerce_status”。

我的腳本是:

import psycopg2
conn = psycopg2.connect("host='localhost' port='5432' dbname='Ekodev' user='bn_openerp' password='fa05844d'")
cur = conn.cursor()
cur.execute("""truncate table "meta".temp_unicommerce_status;""")
cur.execute("""Copy temp_unicommerce_status from 'C:\Users\n\Desktop\data.csv';""")
conn.commit()
conn.close()

我收到此錯誤

Traceback (most recent call last):
  File "C:\Users\n\Documents\NetBeansProjects\Unicommerce_Status_Update\src\unicommerce_status_update.py", line 5, in <module>
cur.execute("""Copy temp_unicommerce_status from     'C:\\Users\\n\\Desktop\\data.csv';""")
psycopg2.ProgrammingError: must be superuser to COPY to or from a file
HINT:  Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.

使用copy_from游標方法

f = open(r'C:\Users\n\Desktop\data.csv', 'r')
cur.copy_from(f, temp_unicommerce_status, sep=',')
f.close()

該文件必須作為對象傳遞。

由於您正在處理 csv 文件,因此有必要指定分隔符,因為默認值是制表符

我解決這個問題的方式特別是使用psychopg2 游標類函數copy_expert(文檔: http ://initd.org/psycopg/docs/cursor.html)。 copy_expert 允許您使用 STDIN,因此無需為 postgres 用戶頒發超級用戶權限。 您對文件的訪問取決於客戶端 (linux/windows/mac) 用戶對文件的訪問

來自 Postgres COPY Docs ( https://www.postgresql.org/docs/current/static/sql-copy.html ):

不要將 COPY 與 psql 指令 \\copy 混淆。 \\copy 調用 COPY FROM STDIN 或 COPY TO STDOUT,然后在 psql 客戶端可訪問的文件中獲取/存儲數據。 因此,當使用 \\copy 時,文件可訪問性和訪問權限取決於客戶端而不是服務器。

您還可以保留嚴格設置的權限以訪問 development_user 主文件夾和 App 文件夾。

csv_file_name = '/home/user/some_file.csv'
sql = "COPY table_name FROM STDIN DELIMITER '|' CSV HEADER"
cursor.copy_expert(sql, open(csv_file_name, "r"))
#sample of code that worked for me

import psycopg2 #import the postgres library

#connect to the database
conn = psycopg2.connect(host='localhost',
                       dbname='database1',
                       user='postgres',
                       password='****',
                       port='****')  
#create a cursor object 
#cursor object is used to interact with the database
cur = conn.cursor()

#create table with same headers as csv file
cur.execute("CREATE TABLE IF NOT EXISTS test(**** text, **** float, **** float, **** 
text)")

#open the csv file using python standard file I/O
#copy file into the table just created 
with open('******.csv', 'r') as f:
next(f) # Skip the header row.
    #f , <database name>, Comma-Seperated
    cur.copy_from(f, '****', sep=',')
    #Commit Changes
    conn.commit()
    #Close connection
    conn.close()


f.close()

以下是相關 PostgreSQL 文檔的摘錄:帶有文件名的 COPY 指示 PostgreSQL 服務器直接讀取或寫入文件。 服務器必須可以訪問該文件,並且必須從服務器的角度指定名稱。 當指定 STDIN 或 STDOUT 時,數據通過客戶端和服務器之間的連接傳輸

這就是為什么copy命令到文件 a 或從文件 a 限制為 PostgreSQL 超級用戶的原因:該文件必須存在於服務器上並由服務器進程直接加載。

你應該改用:

cur.copy_from(r'C:\Users\n\Desktop\data.csv', temp_unicommerce_status)

正如另一個答案所建議的那樣,因為它在內部使用來自標准輸入的COPY

您可以使用d6tstack這使這變得簡單

import d6tstack
import glob

c = d6tstack.combine_csv.CombinerCSV([r'C:\Users\n\Desktop\data.csv']) # single-file
c = d6tstack.combine_csv.CombinerCSV(glob.glob('*.csv')) # multi-file
c.to_psql_combine('postgresql+psycopg2://psqlusr:psqlpwdpsqlpwd@localhost/psqltest', 'tablename')

它還處理 數據模式更改、創建/追加/替換表並允許您使用 Pandas 預處理數據。

我知道這個問題已經得到回答,但這是我的兩分錢。 我添加了更多描述:

您可以使用cursor.copy_from方法:

首先,您必須創建一個與 csv 文件具有相同列數的表。

例子:

我的 csv 看起來像這樣:

Name,       age , college , id_no , country , state   , phone_no

demo_name   22  , bdsu    , 1456  , demo_co , demo_da , 9894321_

首先創建一個表:

import psycopg2
from psycopg2 import Error

connection = psycopg2.connect(user = "demo_user",
                                  password = "demo_pass",
                                  host = "127.0.0.1",
                                  port = "5432",
                                  database = "postgres")
cursor = connection.cursor()


create_table_query = '''CREATE TABLE data_set
(Name  TEXT NOT NULL ,
age  TEXT NOT NULL ,
college  TEXT NOT NULL ,
id_no TEXT NOT NULL ,
country TEXT NOT NULL ,
state TEXT NOT NULL ,
phone_no TEXT NOT NULL);'''

cursor.execute(create_table_query)
connection.commit()

現在您可以簡單地在需要三個參數的地方使用 cursor.copy_from :

first file object , second table_name , third sep type

你現在可以復制:

f = open(r'final_data.csv', 'r')
cursor.copy_from(f, 'data_set', sep=',')
f.close()

完畢

我將發布一些我在嘗試將 csv 文件復制到基於 linux 的系統上的數據庫時遇到的錯誤......

這是一個示例 csv 文件:

Name Age Height
bob  23   59
tom  56   67
  1. 您必須安裝庫 psycopg2(即 pip install psycopg2 或 sudo apt install python3-psycopg2 )

  2. 您必須先在系統上安裝 postgres,然后才能使用 psycopg2(sudo apt install postgresql-server postgresql-contrib)

  3. 現在您必須創建一個數據庫來存儲 csv,除非您已經使用預先存在的數據庫設置了 postgres

使用 POSTGRES 命令復制 CSV

  • 安裝 postgres 后,它會創建一個默認用戶帳戶,讓您可以訪問 postgres 命令

  • 切換到 postgres 帳戶問題: sudo -u postgres psql

  • 通過發出以下命令訪問提示: psql

    #command 創建數據庫 create database mytestdb; #連接數據庫創建表\\connect mytestdb; #創建一個具有相同 csv 列名的表 create table test(name char(50), age char(50), height char(50)); #copy csv file to table copy mytestdb 'path/to/csv' with csv header;

使用 PYTHON 復制 CSV我在將 CSV 文件復制到數據庫時遇到的主要問題是我還沒有創建數據庫,但是這仍然可以用 python 完成。

import psycopg2 #import the Postgres library

#connect to the database
conn = psycopg2.connect(host='localhost',
                       dbname='mytestdb',
                       user='postgres',
                       password='')  
#create a cursor object 
#cursor object is used to interact with the database
cur = conn.cursor()

#create table with same headers as csv file
cur.execute('''create table test(name char(50), age char(50), height char(50));''')

#open the csv file using python standard file I/O
#copy file into the table just created 
f = open('file.csv','r')
cursor.copy_from(f, 'test', sep=',')
f.close()
import os
if '__main__' == __name__:
    cmd = "PGPASSWORD=pwd psql -h host -p port -U username -d dbname -c 'copy tablename from stdin' < '{}'".format(filepath)
    os.system(cmd)

嘗試與 root 用戶執行相同的操作 - postgres。 如果是 linux 系統,您可以更改文件的權限或將文件移動到 /tmp。 該問題是由於缺少從文件系統讀取的憑據造成的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM