Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用python将数据从csv复制到postgresql_Python_Postgresql_Psycopg2_Postgresql Copy - Fatal编程技术网

使用python将数据从csv复制到postgresql

使用python将数据从csv复制到postgresql,python,postgresql,psycopg2,postgresql-copy,Python,Postgresql,Psycopg2,Postgresql Copy,我使用的是64位windows 7。 我有一个csv文件“data.csv”。 我想通过python脚本将数据导入postgresql表“temp\u unicommerce\u status” 我的剧本是: import psycopg2 conn = psycopg2.connect("host='localhost' port='5432' dbname='Ekodev' user='bn_openerp' password='fa05844d'") cur = conn.cursor()

我使用的是64位windows 7。 我有一个csv文件“data.csv”。 我想通过python脚本将数据导入postgresql表“temp\u unicommerce\u 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.
回溯(最近一次呼叫最后一次):
文件“C:\Users\n\Documents\NetBeansProjects\Unicommerce\u Status\u Update\src\Unicommerce\u Status\u Update.py”,第5行,在
当前执行(““从'C:\\Users\\n\\Desktop\\data.csv';”“”复制临时unicommerce\u状态”)
psycopg2.ProgrammingError:必须是超级用户才能复制到文件或从文件复制
提示:任何人都可以复制到标准输出或标准输入。psql的\copy命令也适用于任何人。

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

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

这就是为什么将
copy
命令复制到文件或从文件复制到PostgreSQL超级用户的原因:该文件必须存在于服务器上,并由服务器进程直接加载

您应改为使用:

cur.copy_from(r'C:\Users\n\Desktop\data.csv', temp_unicommerce_status)
正如所建议的,因为它在内部使用stdin的
复制

使用

文件必须作为对象传递


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

我解决此问题的方法,特别是使用Psycopg2 cursor类函数copy_expert(Docs:)。copy_expert允许您使用STDIN,因此无需为postgres用户颁发超级用户权限。然后,您对该文件的访问权取决于客户端(linux/windows/mac)用户对该文件的访问权

从Postgres复制文档():

不要将COPY与psql指令\COPY混淆\复制调用 从STDIN复制或复制到STDOUT,然后在 psql客户端可以访问的文件。因此,文件可访问性和 \copy时,访问权限取决于客户端而不是服务器 使用

您还可以严格保留对development_用户主文件夹和应用程序文件夹的访问权限设置

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"))
您可以使用它来简化此操作

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预处理数据。

我知道这个问题已经得到了回答,但这是我的两分钱。我再补充一点说明:

您可以使用
光标。从
复制\u方法:

首先,您必须创建一个与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_即可,其中需要三个参数:

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
  • 必须安装库psycopg2(即pip安装psycopg2或sudo-apt安装python3-psycopg2)

  • 必须先在系统上安装postgres,然后才能使用psycopg2(sudo apt install postgresql server postgresql contrib)

  • 现在,您必须创建一个数据库来存储csv,除非您已经使用已有的数据库设置了postgres

  • 使用POSTGRES命令复制CSV

    • 安装postgres后,它会创建一个默认用户帐户,允许您访问postgres命令

    • 切换到postgres帐户问题:sudo-u postgres psql

    • 通过发出:psql来访问提示

      #命令创建数据库 创建数据库mytestdb; #连接到数据库以创建表 \连接mytestdb; #创建具有相同csv列名的表 创建表测试(名称字符(50)、年龄字符(50)、高度字符(50)); #将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()
    
    #适用于我的代码示例
    导入psycopg2#导入postgres库
    #连接到数据库
    conn=psycopg2.connect(host='localhost',
    dbname='database1',
    user='postgres',
    密码='***',
    端口=“**”)
    #创建一个游标对象
    #游标对象用于与数据库交互
    cur=连接光标()
    #创建与csv文件标题相同的表
    cur.execute(“如果不存在,则创建表测试(****文本,***浮点,****浮点,****
    案文)“)
    #使用python标准文件I/O打开csv文件
    #将文件复制到刚刚创建的表中
    将open('******.csv',r')作为f:
    下一步(f)#跳过标题行。
    #f,逗号分隔
    当前从(f,'**',sep=',复制_)
    #提交更改
    康涅狄格州提交
    #密切联系
    康涅狄格州关闭
    f、 关闭()
    
    这(和复制专家)不需要超级用户角色吗?它不是从STDIN开始的,这避免了超级用户角色。从文件复制需要用户,这看起来是这样的。我的问题是它运行,但什么也不做,我认为超级用户错误正在悄无声息地失败。我可以确认,copy_from适用于aws rds postgresql实例,在该实例中,您实际上只被授予了rds_超级用户,而不是超级用户。我能够使用STDIN使用copy_expert通过csv文件传播数据库。这样就不需要在postgres中为postgres用户角色授予超级用户权限。看到答案了吗
    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()
    
    #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()