我有一个代码文件
mongo.py
,如下所示,将n查询mongo与username
host
password
及其工作连接起来,但是我如何使用sshaddress
username
和身份验证方法连接到sshprivate_key
? private_key
在另一个文件中
这是我的示例
config
与 ssh:
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
我该怎么办?
这对我有用。我检查了上面的 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
除非 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)
channel = transport.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
。
添加了行 db.authenticate(MONGO_USER, MONGO_PASS)
回忆:“在 MONGO 上进行授权!!!”
并转换为 pandas 数据框,如果它对任何人有用(对我来说是)
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
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']
更多信息请参阅另一篇文章:如何使用 pymongo 连接远程 mongodb .