Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLAlchemy, Psycopg2 and Postgresql COPY

Tags:

It looks like Psycopg has a custom command for executing a COPY:

psycopg2 COPY using cursor.copy_from() freezes with large inputs

Is there a way to access this functionality from with SQLAlchemy?

like image 206
EoghanM Avatar asked Oct 29 '12 16:10

EoghanM


People also ask

Can I use SQLAlchemy with PostgreSQL?

This SQLAlchemy engine is a global object which can be created and configured once and use the same engine object multiple times for different operations. The first step in establishing a connection with the PostgreSQL database is creating an engine object using the create_engine() function of SQLAlchemy.

What is the difference between Psycopg2 and SQLAlchemy?

The psycopg2 is over 2x faster than SQLAlchemy on small table. This behavior is expected as psycopg2 is a database driver for postgresql while SQLAlchemy is general ORM library.

What is PostgreSQL Psycopg2?

From PostgreSQL wiki. Psycopg2 is a mature driver for interacting with PostgreSQL from the Python scripting language. It is written in C and provides a means to perform the full range of SQL operations against PostgreSQL databases.

Is Psycopg2 connection thread safe?

Thread and process safetyThe Psycopg module and the connection objects are thread-safe: many threads can access the same database either using separate sessions and creating a connection per thread or using the same connection and creating separate cursors. In DB API 2.0 parlance, Psycopg is level 2 thread safe.


2 Answers

accepted answer is correct but if you want more than just the EoghanM's comment to go on the following worked for me in COPYing a table out to CSV...

from sqlalchemy import sessionmaker, create_engine  eng = create_engine("postgresql://user:pwd@host:5432/db") ses = sessionmaker(bind=engine)  dbcopy_f = open('/tmp/some_table_copy.csv','wb')  copy_sql = 'COPY some_table TO STDOUT WITH CSV HEADER'  fake_conn = eng.raw_connection() fake_cur = fake_conn.cursor() fake_cur.copy_expert(copy_sql, dbcopy_f) 

The sessionmaker isn't necessary but if you're in the habit of creating the engine and the session at the same time to use raw_connection you'll need separate them (unless there is some way to access the engine through the session object that I don't know). The sql string provided to copy_expert is also not the only way to it, there is a basic copy_to function that you can use with subset of the parameters that you could past to a normal COPY TO query. Overall performance of the command seems fast for me, copying out a table of ~20000 rows.

http://initd.org/psycopg/docs/cursor.html#cursor.copy_to http://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.Engine.raw_connection

like image 153
dnfehren Avatar answered Sep 20 '22 14:09

dnfehren


If your engine is configured with a psycopg2 connection string (which is the default, so either "postgresql://..." or "postgresql+psycopg2://..."), you can create a psycopg2 cursor from an SQL Alchemy session using

cursor = session.connection().connection.cursor() 

which you can use to execute

cursor.copy_from(...) 

The cursor will be active in the same transaction as your session currently is. If a commit or rollback happens, any further use of the cursor with throw a psycopg2.InterfaceError, you would have to create a new one.

like image 30
dtheodor Avatar answered Sep 22 '22 14:09

dtheodor