【问题标题】:Connecting to PostgreSQL database through SSH tunneling in Python在 Python 中通过 SSH 隧道连接到 PostgreSQL 数据库
【发布时间】:2016-04-30 04:21:50
【问题描述】:

我正在尝试远程连接到服务器,然后使用 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')

【问题讨论】:

    标签: python database postgresql ssh ssh-tunnel


    【解决方案1】:

    我不知道这是否有帮助,但我也必须通过 SSH 隧道连接到 PostgreSQL 数据库。我成功地使用您的代码进行了一些修改:

    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() 后,代码运行良好。此外,“数据库已连接”后缺少引号。 我希望这可能对您有所帮助,感谢您分享您的代码!

    【讨论】:

    • 这个。这是我开始工作的那个,经过 2 周的一次又一次尝试解决方案。我的挑战是我需要在隧道中使用 pem,但我无法弄清楚所有碎片都去了哪里。出色的工作使该解决方案清晰且易于使用。
    • 非常感谢,这是在尝试了许多解决方案后对我有用的解决方案。
    【解决方案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()
    

    【讨论】:

      猜你喜欢
      • 2021-12-02
      • 2015-03-01
      • 2014-07-20
      • 1970-01-01
      • 2013-04-05
      • 1970-01-01
      • 2014-09-17
      • 2015-09-18
      • 2021-09-27
      相关资源
      最近更新 更多