Копировать данные из csv в postgresql с помощью python
Я на windows 7 64 бит.
У меня есть файл csv 'data.csv'.
Я хочу импортировать данные в таблицу postgresql "temp_unicommerce_status" через python script.
Мой Script:
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 \copy command also works for anyone.
Ответы
Ответ 1
Используйте метод copy_from
f = open(r'C:\Users\n\Desktop\data.csv', 'r')
cur.copy_from(f, temp_unicommerce_status, sep=',')
f.close()
Файл должен быть передан как объект.
Поскольку вы работаете с csv файлом, необходимо указать разделитель, поскольку по умолчанию используется символ табуляции
Ответ 2
Способ, которым я решил эту проблему, был связан с использованием функции класса курсора 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.
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"))
Ответ 3
Вот выдержка из соответствующей документации PostgreSQL: COPY с именем файла указывает сервер PostgreSQL на прямое чтение или запись в файл. Файл должен быть доступен для сервера, и имя должно быть указано с точки зрения сервера. Когда указывается STDIN или STDOUT, данные передаются через соединение между клиентом и сервером.
Вот почему команда copy
для или из файла ограничена суперпользователем PostgreSQL: файл должен присутствовать на сервере и загружается непосредственно процессом сервера.
Вместо этого вы должны использовать:
cur.copy_from(r'C:\Users\n\Desktop\data.csv', temp_unicommerce_status)
как было предложено этим другим ответом, потому что внутри он использует copy
из stdin.
Ответ 4
Вы можете использовать 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:[email protected]/psqltest', 'tablename')
Он также касается изменений схемы данных, создания/добавления/замены таблицы и позволяет предварительно обрабатывать данные с помощью панд.
Ответ 5
Я знаю, что на этот вопрос ответили, но вот мои два цента. Я добавляю немного больше описания:
Вы можете использовать метод 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()
сделанный
Ответ 6
Я собираюсь опубликовать некоторые из ошибок, с которыми столкнулся, пытаясь скопировать CSV файл в базу данных в системе на основе Linux....
Вот пример CSV файла:
Name Age Height
bob 23 59
tom 56 67
Вы должны установить библиотеку psycopg2 (то есть pip install psycopg2 или sudo apt install python3-psycopg2)
Прежде чем вы сможете использовать psycopg2, в вашей системе должен быть установлен postgres (sudo apt install postgresql-server postgresql-contrib)
Теперь вы должны создать базу данных для хранения CSV, если у вас уже нет установки postgres с уже существующей базой данных
COPY CSV ИСПОЛЬЗУЯ КОМАНДЫ POSTGRES
После установки postgres он создает учетную запись пользователя по умолчанию, которая дает вам доступ к командам postgres
Чтобы переключиться на проблему с учетной записью postgres: sudo -u postgres psql
Получите доступ к приглашению, введя: psql
Команда для создания базы данных
создать базу данных mytestdb;
подключиться к базе данных, чтобы создать таблицу
\ connect mytestdb;
создать таблицу с такими же именами столбцов CSV
создать тест таблицы (имя символа (50), возраст символа (50), рост символа (50));
скопировать CSV файл в таблицу
скопируйте mytestdb 'path/to/csv' с заголовком csv;
COPY CSV ИСПОЛЬЗУЯ PYTHON
Основная проблема, с которой я столкнулся при копировании файла csv в базу данных, заключалась в том, что у меня еще не было базы данных, но это можно сделать с помощью python.
import psycop2 #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()
Ответ 7
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)
Ответ 8
Попробуйте сделать то же самое, что и пользователь root - postgres. Если это была Linux-система, вы можете изменить права доступа к файлам или переместить файл в /tmp. Проблема возникает из-за отсутствия учетных данных для чтения из файловой системы.