[英]Connect and query Mongo database over SSH with private key in Python
我有一个代码文件mongo.py
如下所示,可以使用username
host
password
连接 n 查询 mongo 及其工作,但是我如何使用 ssh address
username
和身份验证方法private_key
连接到 ssh? 另一个文件中的private_key
这是我使用 ssh 的示例config
:
sql_local = {'mongomdm':{'host':'xx.xxx.xxx.xx', 'user':'aaa', 'pkey':'/Users/satu/dua/tiga/config/settings/googlecloud_dev_rsa'}}
我已经准备好一些参考资料,应该像这样导入库吗?
from paramiko import SSHClient, AutoAddPolicy, RSAKey
from paramiko.auth_handler import AuthenticationException
from scp import SCPClient, SCPException
from io import StringIO
这是我的代码文件mongo.py
import csv
import pandas as pd
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
import config.config as cfg
import config.modules.common as comm
from bson.objectid import ObjectId
class mongoFunc:
def __init__(self):
self.types = 'mongodb'
self.host = cfg.sql_local[self.types]['host']
self.user = cfg.sql_local[self.types]['user']
self.password = cfg.sql_local[self.types]['password']
self.uri = 'mongodb://{user}:{password}@{host}'.format(user = self.user, password = self.password, host = self.host)
def connection(self):
try:
client= MongoClient(self.uri)
client.server_info()
print('Connection Established')
except ConnectionFailure as err:
raise(err)
return client
def get_collection(self, client, database, collection):
self.client= client
self.database= database
self.collection= collection
db= self.client[self.database]
return db[self.collection]
def get_query(self,id_data= None,start_date=None,end_date=None,query=None):
self.id = ObjectId(id_data)
self.start_date = start_date
self.end_date = end_date
self.query = query
if self.end_date:
script= {'date':{'$gt':self.start_date,'$lte':self.end_date}}
if self.end_date is None:
script= {'date':{'$gt':self.start_date}}
if self.id:
script = {'_id':{'$gt':self.id}}
if self.query:
script.update(self.query)
return script
def get_data_to_pandas(self, database, collection, query, skip, limit=None):
self.database = database
self.collection = collection
self.query = query
self.limit = limit
self.skip = skip
self.client = self.connection()
self.collection = self.get_collection(self.client,self.database,self.collection)
if limit:
cursor = self.collection.find(self.query).skip(self.skip).limit(self.limit)
if not limit :
cursor = collection.find(self.query).skip(self.skip)
df = pd.DataFrame(list(cursor))
return df
编辑:
def connection(self):
try:
print('Establishing SSH Connection')
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
if (self.password == ''):
private_key = paramiko.RSAKey.from_private_key_file(self.pkey)
self.client.connect(hostname=self.host, port=self.port, username=self.user, pkey=private_key, allow_agent=False,look_for_keys=False)
print("Connected to the server"),self.host
else:
self.client.connect(hostname=self.host, port=self.port, username=self.user, password=self.password, allow_agent=False,look_for_keys=False)
print("Connected to the server"),self.host
except paramiko.AuthenticationException:
print("Authentication failed, please verify your credentials")
result_flag = False
except paramiko.SSHException as sshException:
print("Could not establish SSH connection: %s") % sshException
result_flag = False
else:
result_flag = True
return result_flag
def get_collection(self, client, database, collection):
self.client= client
self.database= database
self.collection= collection
db= self.client[self.database]
return db[self.collection]`
我收到一个错误:
line 64, in get_collection
db= self.client[self.database]
TypeError: 'bool' object is not subscriptable
我应该怎么办?
除非 MongoClient 模块自己支持 SSH 隧道(我不知道),否则您必须明确实现端口转发。
使用 Python Paramiko 修改来自嵌套 SSH的代码进行数据库隧道,您会得到如下代码:
ssh_client = paramiko.SSHClient()
# ...
ssh_client.connect(hostname=ssh_hostname, username=ssh_username, key_filename=ssh_key)
transport = ssh_client.get_transport()
dest_addr = (mongo_host, mongo_port)
local_unique_port = 4000 # any unused local port
local_host = 'localhost'
local_addr = (local_host, local_unique_port)
vmchannel = vmtransport.open_channel("direct-tcpip", dest_addr, local_addr)
self.uri = 'mongodb://{user}:{password}@{local_host}:{port}'.
format(user=mongo_user, password=mongo_password, local_host=local_host,
port=local_unique_port)
如果 Mongo 数据库在 SSH 服务器本身上运行,那么它通常只会在环回接口上侦听。 在这种情况下mongo_host
应该设置为localhost
。
关于 PostgreSQL 的相同问题:使用 Paramiko设置 SSH 隧道以访问 PostgreSQL 。
这对我有用。 我检查了上面的 paramiko 示例,但不明白并发现了这一点。 我从这里获取了代码,并根据我的需要进行了一些修改。
def data_call(collection_name, query={}):
from sshtunnel import SSHTunnelForwarder
import pymongo
MONGO_HOST = 'HOST'
SERVER_USER = 'server_user'
PRIVATE_KEY ='pem.txt'
MONGO_USER='user_mongo'
MONGO_PASS ='pass_mongo'
MONGO_DB = "db"
# define ssh tunnel
server = SSHTunnelForwarder(
MONGO_HOST,
ssh_username=SERVER_USER,
ssh_pkey=PRIVATE_KEY,
remote_bind_address=('127.0.0.1', 27017)
)
# start ssh tunnel
server.start()
connection = pymongo.MongoClient('127.0.0.1', server.local_bind_port)
db = connection[MONGO_DB]
data = db[collection_name].find(query)
return data
在您的连接信息中:
sql_local = {
'mongomdm': {
'host':'xx.xxx.xxx.xx',
'user':'aaa',
'pkey':'/Users/satu/dua/tiga/config/settings/googlecloud_dev_rsa'}}
您可以pip install ssh-pymongo
,然后:
from ssh_pymongo import MongoSession
session = MongoSession('xx.xxx.xxx.xx',
user='aaa',
key='/Users/satu/dua/tiga/config/settings/googlecloud_dev_rsa',
uri='mongodb://{mongo-user}:{mongo-password}@{host}:{local-port}'
)
db = session.connection['db-name']
有关另一篇文章的更多信息: 如何将远程 mongodb 与 pymongo 连接。
只是改进了其他一些实际上对我有帮助的答案
添加了行 db.authenticate(MONGO_USER, MONGO_PASS)
回忆:“在 MONGO 上进行授权!!!!”
并转换为 pandas dataframe 如果它对任何人有用(对我来说是这样)
from sshtunnel import SSHTunnelForwarder
import pymongo
import pandas as pd
def data_call(collection_name, query={}):
MONGO_HOST = 'ip.add.res'
SERVER_USER = 'user'
PRIVATE_KEY = 'PATH TO/id_rsa'
MONGO_USER = 'mongouser'
MONGO_PASS = 'mongopass'
MONGO_DB = "dbname"
# define ssh tunnel
server = SSHTunnelForwarder(
MONGO_HOST,
ssh_username=SERVER_USER,
ssh_pkey=PRIVATE_KEY,
remote_bind_address=('127.0.0.1', dbport)
)
# start ssh tunnel
server.start()
connection = pymongo.MongoClient('localhost', server.local_bind_port)
db = connection[MONGO_DB]
db.authenticate(MONGO_USER, MONGO_PASS)
data = pd.DataFrame(list(db[collection_name].find(query))).drop(columns=['_id'])
return data
`def connection(self):
try:
print('Establishing SSH Connection')
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
if (self.password == ''):
private_key = paramiko.RSAKey.from_private_key_file(self.pkey)
self.client.connect(hostname=self.host, port=self.port, username=self.user, pkey=private_key, allow_agent=False,look_for_keys=False)
print("Connected to the server"),self.host
else:
self.client.connect(hostname=self.host, port=self.port, username=self.user, password=self.password, allow_agent=False,look_for_keys=False)
print("Connected to the server"),self.host
except paramiko.AuthenticationException:
print("Authentication failed, please verify your credentials")
result_flag = False
except paramiko.SSHException as sshException:
print("Could not establish SSH connection: %s") % sshException
result_flag = False
else:
result_flag = True
return result_flag
def get_collection(self, client, database, collection):
self.client= client
self.database= database
self.collection= collection
db= self.client[self.database]
return db[self.collection]`
我line 64, in get_collection db= self.client[self.database] TypeError: 'bool' object is not subscriptable
我应该怎么做?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.