I'm having a little difficulty understanding appropriate syntax for the psycopg3 library in Python. I'm trying to copy the contents of a .csv file into my database. The PostgreSQL documentation indicates copy should be written as follows:
COPY table_name [ ( column_name [, ...] ) ]
FROM { 'filename' | PROGRAM 'command' | STDIN }
[ [ WITH ] ( option [, ...] ) ]
[ WHERE condition ]
so I wrote my python statement as follows:
import psycopg
with psycopg.connect('dbname=ideatest user=postgres password=password') as conn:
with conn.cursor() as cur:
mock_idea_info = open(r'C:\dir\filename.csv')
cur.copy('public.ideastorage FROM C:\dir\filename.csv;')
print('Copy successful.')
The problem is that the script prints 'Copy successful,' but does not insert the data into the db. No error messages are generated. I've duplicated the \ characters in the file path, so that isn't the issue. I've been looking around for solutions and possible troubleshooting methods, but have yet to find anything I understand that seems relevant.
Additionally, is there any way I might be able to pass mock_idea_info directly into the copy statement?
Any assistance would be immensely appreciated.
See Copy from:
cat data.out
1 2
2 1
\d csv_test
Table "public.csv_test"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
col1 | integer | | |
col2 | integer | | |
with open("data.out", "r") as f:
with cur.copy("COPY csv_test FROM STDIN") as copy:
while data := f.read(100):
copy.write(data)
con.commit()
select * from csv_test ;
col1 | col2
------+------
1 | 2
2 | 1
--Add format options
cat data.out
1,2
2,1
with open("data.out", "r") as f:
with cur.copy("COPY csv_test FROM STDIN WITH (FORMAT CSV)" ) as copy:
while data := f.read(100):
copy.write(data)
con.commit()
select * from csv_test ;
col1 | col2
------+------
1 | 2
2 | 1
1 | 2
2 | 1
Above adapted from examples in link. This while data := f.read(100) uses the walrus(:=) only available in Python 3.8+
The following two snippets are working code examples for COPY TO and
COPY FROM statements.
The next example copies the data from the database table cars into the cars.csv file. It also inclues the header row.
Note that we use the new psycopg3 module.
import psycopg
cs = "dbname='testdb' user='postgres' password='s$cret'"
with psycopg.connect(cs) as con:
with con.cursor() as cur:
with open('cars.csv', 'wb') as f:
with cur.copy("COPY cars TO STDOUT WITH CSV HEADER") as copy:
for row in copy:
f.write(row)
The second example copies the data from the CSV file into the database table:
import psycopg
cs = "dbname='testdb' user='postgres' password='s$cret'"
with psycopg.connect(cs) as con:
with con.cursor() as cur:
with open('cars.csv', 'r') as f:
with cur.copy("COPY cars2 FROM STDIN WITH CSV HEADER") as copy:
for line in f:
copy.write(line)
Here is the SQL for testing the examples:
CREATE TABLE cars(id serial PRIMARY KEY, name VARCHAR(255), price INT);
INSERT INTO cars(name, price) VALUES('Audi', 52642);
INSERT INTO cars(name, price) VALUES('Mercedes', 57127);
INSERT INTO cars(name, price) VALUES('Skoda', 9000);
INSERT INTO cars(name, price) VALUES('Volvo', 29000);
INSERT INTO cars(name, price) VALUES('Bentley', 350000);
INSERT INTO cars(name, price) VALUES('Citroen', 21000);
INSERT INTO cars(name, price) VALUES('Hummer', 41400);
INSERT INTO cars(name, price) VALUES('Volkswagen', 21600);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With