Connect postgres and Python - python

I have a database available on a remote host. When I use putty and SSH, I am able to access it. The database itself has no password. Only, the SSH connection has a password. But, when I try to connect to it using Python, it asks for password. I'm new to postgres and paramiko.
Here's what I've tried:
import psycopg2
import paramiko
import time
t = paramiko.Transport(('xxx.com', 22))
t.connect(username="xxx", password='xxx')
c = paramiko.Channel(t)
conn = psycopg2.connect("dbname='xxx'")
curs = conn.cursor()
sql = "select * from xxx"
curs.execute(sql)
rows = curs.fetchall()
print(rows)
Other method that I tried was:
import os, psycopg2
os.system("ssh xxx#xxx.com -fNL 5432:localhost:5432 -p 22")
while True:
try:
conn = psycopg2.connect("dbname='xxx'")
curs = conn.cursor()
sql = "select * from xxx"
curs.execute(sql)
rows = curs.fetchall()
print(rows)
except:
print "I am unable to connect to the database"
This gives me a 'Could not request local forwarding' error.
Is there some other way to go about this?
I have a Windows 7 (x64) machine with Python 2.7. Please help me. Thanks.

You should connect to the remote server and make port forwarding of remote PostgreSQL to a local port.
Without paramiko, it's something like this:
# start port forwarding
$ ssh -L PGSQL_LOCAL_PORT:localhost:PGSQL_REMOTE_PORT user#xxx.com
# in python
psycopg.connect("dbname='xxx' host='localhost' port='PGSQL_LOCAL_PORT'")
Here is an example of doing this with paramiko
https://code.ros.org/trac/wg-ros-pkg/browser/pkg/trunk/paramiko/demos/forward.py?rev=30
Note: Port forwarding is blocking operation. So, you have to start port forwarding in separate thread/process.

Related

PyMySQL using localhost vs socket incoherant behaviour

I am using PyMySQL to connect to a database running on localhost. I can access the database just fine using the username/password combiunation in both the command line and adminer so the database does not appear to be the probem here.
My code is as follow. However, when using the host="127.0.0.1" options, I get an OperationalError and an Errno 111. Using the same code, but connecting via the socket Mariadb runs on is fine.
import pymysql.cursors
from pprint import pprint
# This causes an OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)")
# connection = pymysql.connect(
# host="127.0.0.1",
# port=3306,
# user="root",
# password="S3kr37",
# db="my_test",
# )
# This works.
connection = pymysql.connect(
user="root",
password="S3kr37",
db="my_test",
unix_socket="/var/lib/mysql/mysql.sock"
)
try:
with connection.cursor() as cursor:
sql = "select * from MySuperTable"
cursor.execute(sql)
results = cursor.fetchall()
pprint(results)
finally:
connection.close()
What am I doing wrong?
PS: Note that this question has the same problem but the solution offered is the socket. That is no good enough: I want to know why I cannot use the hostname as the documentation suggests.
Errorcode 2003 (CR_CONN_HOST_ERROR) is returned by the client library, in case the client wasn't able to establish a tcp connection to the server.
First you should check, if you can connect via telnet or mysql command line client to your server.
If not, check the server configuration file:
does the server run on port 3306?
is IPv4 disabled?
is skip-networking enabled?
is bind-address activated (with another IP?

How to connect to a remote Windows machine to change mdb file using python?

I am new to Python and I am trying to make a script that connects to a remote windows machine and change mdb file there. I can’t figure out how to work with the WMI library.
When I need to change mdb file (Access database) on my machine, I just use pyodbc connect. For example like this:
connStr = pyodbc.connect(r'DRIVER={Microsoft Access Driver (*.mdb)};'
r'DBQ=C:\Komax\Data\Topwin\DatabaseServer.mdb;')
cursor = connStr.cursor()
But now I need to run code on my machine so that it modifies the file (mdb) on the other machine. It seems like I have to use this code below to connect to remote machine, but I don't know what to do next, how to use connection. Please, help me to solve the problem :)
ip = "192.168.18.74"
username = "admin"
password = "komax"
from socket import *
try:
print("Establishing connection to %s" % ip)
connection = wmi.WMI(ip, user=username, password=password)
print("Connection established")
except wmi.x_wmi:
print("Your Username and Password of "+getfqdn(ip)+" are wrong.")

Connecting Hive remote server from Python

I have a trouble connecting to hive running on remote server through my python script.
I'm using the same script (With different server details, of course) to connect to hive running on my localhost & am able to connect.
I'm starting the server on local host from command line with a command:
hive —service hiveserver2
That start the server and I run the python script
Script to connect to Hive running on local host:
import pyhs2
conn = pyhs2.connect(host='localhost', port=10000, authMechanism='PLAIN', user='hive', password ='', database='default')
with conn.cursor() as cur:
cur.execute("show databases")
for i in cur.fetch():
print i
Using above code, am able to access db # Hive on local host.
I'm using below code to connect to remote server, here I'm not doing anything on command line to start the remote server.
Script to connect to Hive running on the remote server:
conn = pyhs2.connect(host='<my remote server Ip>', port=<port no>, authMechanism='PLAIN', user='<usernameToConnectToRemoteServer>', password ="<remoteServerPassword>" database='default')
with conn.cursor() as cur:
cur.execute("show databases")
for i in cur.fetch():
print i
and this returns me a message:
thrift.transport.TTransport.TTransportException: TSocket read 0 bytes.
I've tried to google & find the solution, as much as i can, but all I see are the examples to connect to local host. please help me resolve this.
Try doing SSH to your remote machine and then connect to hive like below-
import paramiko
import traceback
def hive_query_executor():
dns_name = ''
conn_obj = paramiko.SSHClient()
conn_obj.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
conn_obj.connect(dns_name, username="hadoop",
key_filename='')# or password
Hive_query="select * from abc limit 10;"
query_execute_command = 'ihive -e "' + impala_query + '"'
std_in, std_out, std_err = conn_obj.exec_command(query_execute_command)
conn_obj.close()
except:
print "Error :" + str(traceback.format_exc())
exit(0)
hive_query_executor()

ssh first with mysqldb in python

I'm trying to connect to a MySQL database on a remote server using MySQLdb in python. The problem is that first I need to SSH into the host, and then from there, I need to connect to the MySQL server. The problem I'm having, though, is that MySQLdb does not seem to have a way of establishing an SSH connection before connecting to the SQL server. I've checked the documentation but have not had any luck.
This is how I'm connecting:
conn = MySQLdb.connect(host = 'mysqlhost.domain.com:3306', user = 'user', passwd = 'password', db = 'dbname')
But what I really need is something like this:
conn = MySQLdb.connect(sshhost = 'sshhost.domain.com', sshuser = 'sshusername', sshpasswd = 'sshpasswd', host = 'mysqlhost.domain.com:3306', user = 'user', passwd = 'password', db = 'dbname')
Which is of course just made up. Can anyone make any recommendations?
I prefer keeping the tunnel within the python code, I did hate to create tunnels manually, or separately, thanks to sshtunnel library its very simple to use.
Here is some simple sample that will work for what you want.
import MySQLdb
from sshtunnel import SSHTunnelForwarder
with SSHTunnelForwarder(
('sshhost.domain.com', 22),
ssh_password="sshpasswd",
ssh_username="sshusername",
remote_bind_address=('mysqlhost.domain.com', 3306)) as server:
conn = MySQLdb.connect(host='127.0.0.1',
port=server.local_bind_port,
user='user',
passwd='password',
db='dbname')
Setup an ssh tunnel before you use MySQLdb.connect. The tunnel will make it appear as though you have the mysql running locally, set it up something like this
ssh user#host.com -L 9990:localhost:3306
here your local port 9990 will bind to 3306 on the remote host, -L stands for local, then 9990:localhost:3306 means LOCALPORT:
conn = MySQLdb.connect(host = 'mysqlhost.domain.com:9990', user = 'user', passwd = 'password', db = 'dbname')
notice the 9990.
Add your public ssh key of user to the host.com so that you dont have to type the password each time you want to setup the tunnel (use public key authentication).
If you need to do this within python there is python-to-ssh binding libraries you could call from within python to setup the tunnel for you.

PyMySQL can't connect to MySQL on localhost

I'm trying to connect to MySQL on localhost using PyMySQL:
import pymysql
conn = pymysql.connect(db='base', user='root', passwd='pwd', host='localhost')
but (both on Python 2.7 and Python 3.2) I get the error:
socket.error: [Errno 111] Connection refused
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' (111)")
I'm sure mysqld is running because I can connect using mysql command or phpMyAdmin. Moreover, I can connect using MySQLdb on Python 2 with nearly the same code:
import MySQLdb
conn = MySQLdb.connect(db='base', user='root', passwd='pwd', host='localhost')
It seems that the problem is on PyMySQL side rather than MySQL but I have no idea how to solve it.
Two guesses:
Run mysqladmin variables | grep socket to get where the socket is located, and try setting up a connection like so:
pymysql.connect(db='base', user='root', passwd='pwd', unix_socket="/tmp/mysql.sock")
Run mysqladmin variables | grep port and verify that the port is 3306. If not, you can set the port manually like so:
pymysql.connect(db='base', user='root', passwd='pwd', host='localhost', port=XXXX)
Seems like changing localhost to 127.0.0.1 fixes the error, at least in my configuration.
If it doesn't, I would look for errors in tcp sockets connection and, of course, post it as a bug in pymysql bugtrack.
I solved the issue by replacing localhost with 127.0.0.1 and changing the password to my MYSQL database password as shown below;
conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
passwd = 'XXXXXXXXX',
db = 'mysql'
)
I met the same question and my solution is as follows:
Run ssh -fN -L 3307:mysql_host:3306 ssh_user#ssh_host in my terminal.
Then input your ssh password
conn = pymysql.connect(db='base', user='root', passwd='pwd', host='localhost')
This error occurs because database does not support link directly.
I asked why socket worked but not TCP and the answer was that bind-address in /etc/my.cnf was not set correctly. This could be your problem too since the socket methods works just fine but the TCP one does not.
Those who are strugging to connect localhost MySQL from dockerised flask-sqlalchemy or using pymysql, pls look into this thread, very usefull How to connect locally hosted MySQL database with the docker container
This worked for me:
import pymysql
db = pymysql.connect(host="localhost",port=8889,user="root",passwd="root")
cursor=db.cursor()
cursor.execute("SHOW DATABASES")
results=cursor.fetchall()
for result in results:
print (result)
if you want to find the port # go to mysql in terminal, and type:
SHOW VARIABLES WHERE Variable_name = 'hostname';
SHOW VARIABLES WHERE Variable_name = 'port';
I had this same problem on AWS - and turns out that my security group was blocking the connection. I temporarily opened up all connections and voila! It connected!
Do you have any type of FW or host-based FW that could be blocking the connection? I thought it was my code and all was fine. Also check the port you are connecting on.
If you are using Docker, you might need to use host.docker.internal instead of localhost.
I managed to solve my issue by using the port without any quotation like so:
port = 3306,
You need to add the port to the connection as well. Try this and it works fine.
pymysql(Module Name).connect(host="localhost", user="root", passwd="root", port=8889, db="db_name")

Categories

Resources