30

我在 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.
4

8 回答 8

34

使用copy_from游标方法

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

该文件必须作为对象传递。

由于您正在处理 csv 文件,因此有必要指定分隔符,因为默认值是制表符

于 2015-05-05T17:50:19.757 回答
8

我解决这个问题的方法特别是使用psychopg2游标类函数copy_expert(文档:http://initd.org/psycopg/docs/cursor.html 。copy_expert 允许您使用 STDIN,因此无需为 postgres 用户颁发超级用户权限。然后,您对文件的访问取决于客户端 (linux/windows/mac) 用户对文件的访问

来自 Postgres COPY 文档(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"))
于 2018-08-16T17:52:42.090 回答
5
#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()
于 2020-08-09T19:13:27.720 回答
2

以下是相关 PostgreSQL 文档的摘录:带有文件名的 COPY 指示 PostgreSQL 服务器直接读取或写入文件。服务器必须可以访问该文件,并且必须从服务器的角度指定名称。当指定 STDIN 或 STDOUT 时,数据通过客户端和服务器之间的连接传输

这就是为什么copy文件的命令仅限于 PostgreSQL 超级用户的原因:该文件必须存在于服务器上并且由服务器进程直接加载。

您应该改用:

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

正如其他答案所建议的那样,因为它在内部使用COPY标准输入。

于 2015-05-05T10:32:38.143 回答
1

您可以使用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 预处理数据。

于 2018-12-04T04:02:00.793 回答
1

我知道这个问题已经得到解答,但这是我的两分钱。我正在添加更多描述:

您可以使用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()

完毕

于 2019-01-23T09:19:03.263 回答
0

我将发布一些我在尝试将 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

    #创建数据库命令 create database mytestdb; #连接数据库创建表 \connect mytestdb; #创建一个具有相同csv列名的表 create table test(name char(50), age char(50), height char(50)); #copy csv 文件到表复制 mytestdb 'path/to/csv' 和 csv 头;

使用 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()
于 2019-10-14T16:10:35.430 回答
-2

尝试做与 root 用户相同的操作 - postgres。如果是 linux 系统,您可以更改文件的权限或将文件移动到 /tmp。该问题是由于缺少从文件系统读取的凭据造成的。

于 2015-05-05T10:29:08.060 回答