Vous êtes sur la page 1sur 3

Connecting to Postgresql database through

SSH tunneling in Python


Ask Question

2
3
I am trying to connect to connect to a server remotely and then access it's local
database with python. I am successfully connecting to the server, although I can't seem
to connect to the database on the server. My code is below:

import psycopg2
from sshtunnel import SSHTunnelForwarder

try:

with SSHTunnelForwarder(
('<server ip address>', 22),
ssh_private_key="</path/to/private/ssh/key>",
ssh_username="<server username>",
remote_bind_address=('localhost', 5432)) as server:

print "server connected"

conn = psycopg2.connect(database="<dbname>",port=server.local_bind_port)
curs = conn.cursor()
print "database connected

except:
print "Connection Failed"
This is bits and pieces of example code I have found around the internet. I have also
tried the connection statements below in place of the connect ones above:

params = {
'database': '<dbname>',
'user': '<dbusername>',
'password': '<dbuserpass>',
'host': 'localhost',
'port': 5432
}
conn = psycopg2.connect(**params)
I know I can connect to the database because on my machine; I am able to
use sqlectron to tunnel in and connect appropriately.
Just in case it is not clear what I am trying to do from above, I need to ssh tunnel into
my remote server using a private ssh key on my computer (working properly), and then
I need to connect to a PostgreSQL database that is on localhost at port 5432.
I am currently getting the current error message for both ways of trying to connect:

2016-01-23 11:16:10,978 | ERROR | Tunnel: 0.0.0.0:49386 <> localhost:5432 error: (9, 'Bad file
descriptor')

python database postgresql ssh ssh-tunnel

shareimprove this question


edited Jan 24 '16 at 9:13

Will
16.8k106182
asked Jan 23 '16 at 16:22

Mark
1113
add a comment
2 Answers
activeoldest votes

3
I don't know if this may be helpful, but I had to connect to a Postgresql database
through SSH tunneling as well. I succeded to connect using your code with some
modifications:

import psycopg2
from sshtunnel import SSHTunnelForwarder

try:

with SSHTunnelForwarder(
('<server ip address>', 22),
#ssh_private_key="</path/to/private/ssh/key>",
### in my case, I used a password instead of a private key
ssh_username="<server username>",
ssh_password="<mypasswd>",
remote_bind_address=('localhost', 5432)) as server:

server.start()
print "server connected"

params = {
'database': '<dbname>',
'user': '<dbusername>',
'password': '<dbuserpass>',
'host': 'localhost',
'port': local_bind_port
}

conn = psycopg2.connect(**params)
curs = conn.cursor()
print "database connected"

except:
print "Connection Failed"
After adding server.start(), the code worked nicely. Furthermore, inverted commas were
missing after 'database connected'. I hope this might be helpful to you, thanks for
sharing your code!
shareimprove this answer
edited Sep 11 '17 at 6:36

Uwe
24.5k75577
answered May 6 '16 at 17:19
Aliossandro
3811
 I tried the above code but I am see the following error HandlerSSHTunnelForwarderError: In #1 <--
('127.0.0.1', 53281) to ('10.160.1.24', 5432) failed: ChannelException(2, 'Connect failed').
Any idea what I could be doing wrong? – Pradeep Vairamani Jun 23 '16 at 19:56
add a comment
2
Both these examples were very helpful. I had an issue with binding the local port
manually in the db connection. We have a dynamic port on our server I guess? I
combined elements of the two examples. Using sever.local_bind_port may be a more
robust and dynamic resolution.

from sshtunnel import SSHTunnelForwarder #Run pip install sshtunnel


from sqlalchemy.orm import sessionmaker #Run pip install sqlalchemy

with SSHTunnelForwarder(
('<remote server ip>', 22), #Remote server IP and SSH port
ssh_username = "<username>",
ssh_password = "<password>",
remote_bind_address=('<local server ip>', 5432)) as server: #PostgreSQL server IP and sever port
on remote machine

server.start() #start ssh sever


print 'Server connected via SSH'

#connect to PostgreSQL
local_port = str(server.local_bind_port)
engine = create_engine('postgresql://<username>:<password>@127.0.0.1:' + local_port
+'/database_name')

Session = sessionmaker(bind=engine)
session = Session()

print 'Database session created'

#test data retrieval


test = session.execute("SELECT * FROM database_table")
for row in test:
print row['id']

session.close()

Vous aimerez peut-être aussi