Join the Stack Overflow Community
Stack Overflow is a community of 6.5 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

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')
share|improve this question

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!

share|improve this answer
    
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

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()
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.