Скопировать данные из csv в postgresql, используя python

Я на Windows 7 64 бит. У меня есть CSV-файл "data.csv". Я хочу импортировать данные в таблицу postgresql 'temp_unicommerce_status' с помощью скрипта Python.

Мой сценарий:

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.

5 ответов

Решение

Использовать 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 (Docs: 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.

sql = "COPY table_name FROM STDIN DELIMITER '|' CSV HEADER"
        self._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 команда для файла или из файла, доступного только суперпользователю 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')

Он также имеет дело с изменениями схемы данных, создает / добавляет / заменяет таблицу и позволяет предварительно обрабатывать данные пандами.

Я знаю, что на этот вопрос ответили, но вот мои два цента. Я добавляю немного больше описания:

Ты можешь использовать 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 с уже существующей базой данных.

КОПИРОВАТЬ CSV С ПОМОЩЬЮ КОМАНД POSTGRES

  • После установки 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 file to table copy mytestdb 'path/to/csv' с заголовком csv;

КОПИРОВАНИЕ CSV С ИСПОЛЬЗОВАНИЕМ PYTHON Основная проблема, с которой я столкнулся при копировании файла 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()

Лучший ответ: PGPASSWORD pwd psql -h host -p port -U username -d dbname -c "копировать имя таблицы в стандартный вывод" > filepath

Попробуйте сделать то же самое, что и пользователь root - postgres. Если бы это была система Linux, вы могли бы изменить права доступа к файлу или переместить файл в /tmp. Проблема возникает из-за отсутствия учетных данных для чтения из файловой системы.

Другие вопросы по тегам