Подключение к базе данных PostgreSQL через SSH-туннель в Python

Я пытаюсь удаленно подключиться к серверу, а затем получить доступ к его локальной базе данных с помощью Python. Я успешно подключаюсь к серверу, хотя не могу подключиться к базе данных на сервере. Мой код ниже:

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"

Это фрагменты кода, которые я нашел в Интернете и собрал вместе. Я также пробовал приведенные ниже операторы подключения вместо приведенного выше кода:

params = {
  'database': '<dbname>',
  'user': '<dbusername>',
  'password': '<dbuserpass>',
  'host': 'localhost',
  'port': 5432
}
conn = psycopg2.connect(**params)

Я знаю, что могу подключиться к базе данных, потому что на моем компьютере; Я могу использовать sqlectron для туннелирования и правильного подключения.

На всякий случай неясно, что я пытаюсь сделать сверху, мне нужно ssh-туннель на мой удаленный сервер, используя закрытый ssh-ключ на моем компьютере (работает правильно), а затем мне нужно подключиться к базе данных PostgreSQL, которая является на localhost в порту 5432.

В настоящее время я получаю текущее сообщение об ошибке для обоих способов подключения:

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

person Mark    schedule 23.01.2016    source источник


Ответы (2)


Оба этих примера были очень полезны. Мне просто нужно было объединить хорошие стороны обоих.

from sshtunnel import SSHTunnelForwarder #Run pip install sshtunnel
from sqlalchemy.orm import sessionmaker #Run pip install sqlalchemy
from sqlalchemy import create_engine

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()
person Jason Callahan    schedule 12.05.2016

Не знаю, может ли это быть полезно, но мне также пришлось подключиться к базе данных PostgreSQL через туннелирование SSH. Мне удалось подключиться по вашему коду с некоторыми изменениями:

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': server.local_bind_port
             }

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

except:
    print "Connection Failed"

После добавления server.start() код работал нормально. Кроме того, после слов «база данных подключена» отсутствовали кавычки. Надеюсь, это может быть вам полезно, спасибо, что поделились своим кодом!

person Aliossandro    schedule 06.05.2016
comment
Этот. Это был тот, над которым я приступил к работе после 2 недель пробования решения за решением. Моя проблема заключалась в том, что мне нужно было использовать пем для туннеля, и я не мог понять, куда уходят ВСЕ части. Отличная работа, сделавшая это решение понятным и простым в использовании. - person autonopy; 09.07.2021