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

У меня проблема с подключением к удаленной базе данных через SSH-туннель (сейчас пытаюсь с Paramiko). Вот мой код:

#!/usr/bin/env python3
import psycopg2
import paramiko
import time

#ssh = paramiko.SSHClient()
#ssh.load_system_host_keys()
#ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#ssh.connect('pluton.kt.agh.edu.pl', 22, username='aburban', password='pass')

t = paramiko.Transport(('pluton.kt.agh.edu.pl', 22))
t.connect(username="aburban", password='pass') 
c = paramiko.Channel(t)
conn = psycopg2.connect(database="dotest")
curs = conn.cursor()
sql = "select * from tabelka"
curs.execute(sql)
rows = curs.fetchall()
print(rows)

Проблема в том, что программа всегда пытается подключиться к локальной базе данных. Я пробовал с другими туннелями SSH, и была такая же ситуация. База данных на удаленном сервере существует и отлично работает при "классическом" SSH-соединении через терминал.


person user3690132    schedule 02.01.2015    source источник


Ответы (1)


Вы можете попробовать использовать модуль sshtunnel, который использует Paramiko и совместим с Python 3.

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

Будет просто, сгенерируйте туннель к порту 5432 на локальном хосте удаленного сервера из локального порта, а затем вы используете его для подключения через локальный хост к удаленной БД.

Это будет образец рабочего кода для ваших нужд:

#!/usr/bin/env python3
import psycopg2
from sshtunnel import SSHTunnelForwarder
import time

with SSHTunnelForwarder(
         ('pluton.kt.agh.edu.pl', 22),
         ssh_password="password",
         ssh_username="aburban",
         remote_bind_address=('127.0.0.1', 5432)) as server:

    conn = psycopg2.connect(database="dotest",port=server.local_bind_port)
    curs = conn.cursor()
    sql = "select * from tabelka"
    curs.execute(sql)
    rows = curs.fetchall()
    print(rows)
person jsjc    schedule 08.08.2015