MySQLdb cannot resolve localhost - python

I have set up a basic transactional database using MySQL. Using python/MySQLdb, this works fine:
connection = MySQLdb.connect (host = "127.0.0.1", port = 3306, user = "root", passwd = "password", db = "test")
but this doesn't:
connection = MySQLdb.connect (host = "localhost", port = 3306, user = "root", passwd = "password", db = "test")
Using the latter generates the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "path\to\virtualenv\lib\site-packages\MySQLdb\__init__.py", line 81, in Connect
return Connection(*args, **kwargs)
File "path\to\virtualenv\lib\site-packages\MySQLdb\connections.py", line 187, in __init__
super(Connection, self).__init__(*args, **kwargs2)
_mysql_exceptions.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' (10061)")
I have to admit I'm a bit confused as to why MySQLdb fails to resolve localhost. The C:\Windows\System32\drivers\etc\hosts file hasn't been modified in way. Using a regular Windows command prompt, ping localhost and telnet localhost 3306 both work fine.
Environment:
Windows 7 (64 bits)
Python 2.7.2 (32 bits)
MySQLdb 1.2.3
MySQL 5.5.28 (64 bits)

From MySQLdb docs, about using localhost:
This creates a connection to the MySQL server running on the local
machine via a UNIX socket. UNIX sockets and named pipes don't work
over a network, so if you specify a host other than localhost, TCP
will be used, and you can specify an odd port if you need to.
Your server probably listen on TCP socket.

This may be an IPv6 issue. If so, it can be solved via
http://www.victor-ratajczyk.com/post/2012/02/25/mysql-fails-to-resolve-localhost-disable-ipv6-on-windows.aspx

Related

Connect to Proxy (SOCKS) Database in python

I am trying to connect to a database that needs proxy (socks) to be able to connect, if I use the proxy connection manually, I can connect, but I need to make the script connect to the proxy (socks) of the machine to make this SELECT
SCRIPT
import socket
import socks
import requests
import pymssql
socks.set_default_proxy(socks.SOCKS5, "138.34.133.155", 1080, True, 'user','password')
socket.socket = socks.socksocket
server = '172.43.56.89'
username = 'user'
password = 'password'
database = 'dbname'
conn = requests.get(pymssql.connect(host=server,user=username,password=password,database=database))
cursor = conn.cursor()
cursor.execute("SELECT column FROM table")
row = cursor.fetchall()
conn.close()
for i in row:
print(i)
OUTPUT
Traceback (most recent call last): File "connection.py", line 15, in
conn = requests.get(pymssql.connect(host=server,user=username,password=password,database=database))
File "src\pymssql.pyx", line 642, in pymssql.connect
pymssql.OperationalError: (20009, 'DB-Lib error message 20009,
severity 9:\nUnable to connect: Adaptive Server is unavailable or does
not exist (172.43.56.89:1433)\nNet-Lib error during Unknown error
(10060)\n')
I think an option is to mount a local tunnelling sock with port forwarding, to map your database port and act as if your server where a localhost one.
It's really efficient if you're running your python script on a Unix computer.
Something like this system call (for a 3306 mariaDB) :
ssh -L 3306:localhost:3306 user#x.x.x.x
First, your run SSH, then, you tell him to enable a port forwarding from the 3306 port to the localhost:3306 port of the server you connect through user#IP.
With this, every query from your local machine:3306 will by send to your MariaDB:3306 server, allowing you to use it as if you where on the server.
If you do not want to hack into pymssql source code, there're external tools that redirect all TCP traffic over the socks proxy, such as FreeCap for Windows, RedSocks for Linux and Proximac for macOS.

How to specify port number using mysql-connector-python (error 2003)

I am trying to connect via SSH to a MySQL server from my local Windows machine. The SSH connection works fine, but I am unable to connect to the MySQL server when running the following Python script:
import mysql.connector
import sys
import time
import paramiko
host = 'remote-ssh-host'
i = 1
while True:
print("Trying to connect to %s (%i/30)" % (host, i))
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port=22, username='sshuser', password='sshpwd')
print("Connected to %s" % host)
break
except paramiko.AuthenticationException:
print("Authentication failed when connecting to %s" % host)
sys.exit(1)
except:
print("Could not SSH to %s, waiting for it to start" % host)
i += 1
time.sleep(2)
# If we could not connect within time limit
if i == 30:
print("Could not connect to %s. Giving up" % host)
sys.exit(1)
cnx = mysql.connector.connect(user="mysqluser", password="mysqlpwd",
host="mysqlhost",
port=3307)
Here is the output:
Trying to connect to remote-ssh-host (1/30)
Connected to remote-ssh-host
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\mysql\connector\network.py", line 469, in open_connection
self.sock.connect(sockaddr)
TimeoutError: [WinError 10060]
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\path\to\script\ssh_mysql_test.py", line 50, in <module>
port="3307"
...
File "C:\Python34\lib\site-packages\mysql\connector\network.py", line 472, in open_connection
errno=2003, values=(self.get_address(), _strioerror(err)))
mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL server on 'mysqlhost:3307' (10060)
Similar questions have been asked here and here, but I think this problem has to do with the way mysql-connector-python handles the connection string for the port number, because when using the Putty terminal I can make it work:
login as: sshuser
sshuser#remote-ssh-host's password:
sshuser#remote-ssh-host:~$ mysql -h mysqlhost -P 3307 -u mysqluser -p
Enter password:
...
mysql>
But, when specifying the port number in the same way as e.g. the mysql-connector-python does:
login as: sshuser
sshuser#remote-ssh-host's password:
sshuser#remote-ssh-host:~$ mysql -h mysqlhost:3307 -u mysqluser -p
Enter password:
ERROR 2005 (HY000): Unknown MySQL server host 'mysqlhost:3307' (0)
I realize the error numbers are different (2003 vs. 2005), but I think that they are related. So the question actually is: How can I format the port number in such a way that the connection executes as -h hostname -P port instead of -h hostname:port?
The problem is that your ssh and MySQL connections are completely separated. In order for your MySQL connection to work through ssh, you need to tunnel the MySQL connection through the ssh one.
The first SO topic you linked actually provides the answer to this problem: uses an ssh tunnelling component to create the tunnel and the MySQL connection is directed through the tunnel.
server = SSHTunnelForwarder(
('host', 22),
ssh_password="password",
ssh_username="username",
remote_bind_address=('127.0.0.1', 3306))
The above code binds the ssh connection to port 3306 of the localhost. So any connection made to 127.0.0.1:3306 will be tunnelled through the ssh connection to the remote server.
engine = create_engine('mysql+mysqldb://user:pass#127.0.0.1:%s/db' % server.local_bind_port)
In the above code the MySQL connection is made to 127.0.0.1:3306, therefore it will be tunnelled though the ssh connection. You need to follow the same pattern: create an ssh tunnel bound to a local port and in your MySQL connection string specify this local port instead of the remote one.

Connect to external database (mysql) with python

I am trying to connect to my website's MySQL database from my own computer. The script I use:
hostaddress = 'sitedezign.net'
username = '*********'
password = '*********'
database = '*********'
db_port = 3306
#connect
db = _mysql.connect(host=hostaddress,user=username,passwd=password,db=database, port=db_port)
However I get the following error
Traceback (most recent call last):
File "C:\Users\Yorian\Desktop\TU\Stage Shore\python_files\Rectify, metadata and upload\sql_test.py", line 25, in <module>
port=db_port)
OperationalError: (2003, "Can't connect to MySQL server on 'sitedezign.net' (10061)")
I have switched my computer's firewall off and also added an outbound rule to my firewall for when I connect to an outbound port 3306 (to allow this)
The user does have the rights, I've tested this by running a php script with the same login data on the server and it connects perfectly fine (host=localhost)
I set the server to allow external connections coming from my IP address (IPv4 as well as IPV6)
The server is from a webhoster so I can not access the server myself.
Anybody that has an idea where things are going wrong?

MySQLdb connection error with localhost with different port (eg. 8080)

I am trying to connect MySQLdb to MySQL. It was working fine when when my server was localhost and port 80. But due to some reason I had to change the port to 8080. Now how do I specify the port in the connect command?
This is what I was using earlier:
db = MySQLdb.connect(host = "localhost", user = "root", passwd = "", db = "pymysql")
Now my server is "localhost:8080". So where should I give the information regarding this port?
I tried this :
db = MySQLdb.connect(host = "127.0.0.1:8080", user = "root", passwd = "", db = "pymysql")
This is what I got :
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
db = MySQLdb.connect(host = "127.0.0.1:8080", user = "root", passwd = "", db = "pymysql")
File "C:\Python27\lib\site-packages\MySQLdb\__init__.py", line 81, in Connect
return Connection(*args, **kwargs)
File "C:\Python27\lib\site-packages\MySQLdb\connections.py", line 187, in __init__
super(Connection, self).__init__(*args, **kwargs2)
OperationalError: (2005, "Unknown MySQL server host '127.0.0.1:8080' (11004)")
Please Help !!!
You should read the documentation.
connect(parameters...)
host
name of host to connect to. Default: use the local host via a UNIX socket (where applicable)
user
user to authenticate as. Default: current effective user.
passwd
password to authenticate with. Default: no password.
db
database to use. Default: no default database.
port
TCP port of MySQL server. Default: standard port (3306).
The ports 8080 or 80 are usually used for web servers not for MySQL
The default port for MySQL is 3306

MySQLdb connection problems

I'm having trouble with the MySQLdb module.
db = MySQLdb.connect(
host = 'localhost',
user = 'root',
passwd = '',
db = 'testdb',
port = 3000)
(I'm using a custom port)
the error I get is:
Error 2002: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
Which doesn't make much sense since that's the default connection set in my.conf.. it's as though it's ignoring the connection info I give..
The mysql server is definitely there:
[root#baster ~]# mysql -uroot -p -P3000
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 5.0.77 Source distribution
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> use testdb;
Database changed
mysql>
I tried directly from the python prompt:
>>> db = MySQLdb.connect(user='root', passwd='', port=3000, host='localhost', db='pyneoform')
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib64/python2.5/site-packages/MySQLdb/__init__.py", line 74, in Connect
return Connection(*args, **kwargs)
File "/usr/lib64/python2.5/site-packages/MySQLdb/connections.py", line 169, in __init__
super(Connection, self).__init__(*args, **kwargs2)
_mysql_exceptions.OperationalError: (2002, "Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)")
>>>
I'm confused... :(
Changing localhost to 127.0.0.1 solved my problem using MySQLdb:
db = MySQLdb.connect(
host = '127.0.0.1',
user = 'root',
passwd = '',
db = 'testdb',
port = 3000)
Using 127.0.0.1 forces the client to use TCP/IP, so that the server listening to the TCP port can pickle it up. If host is specified as localhost, a Unix socket or pipe will be used.
add unix_socket='path_to_socket' where path_to_socket should be the path of the MySQL socket, e.g. /var/run/mysqld/mysqld2.sock
Make sure that the mysql server is listening for tcp connections, which you can do with netstat -nlp (in *nix). This is the type of connection you are attempting to make, and db's normally don't listen on the network by default for security reasons. Also, try specifying --host=localhost when using the mysql command, this also try to connect via unix sockets unless you specify otherwise. If mysql is not configured to listen for tcp connections, the command will also fail.
Here's a relevant section from the mysql 5.1 manual on unix sockets and troubleshooting connections. Note that the error described (2002) is the same one that you are getting.
Alternatively, check to see if the module you are using has an option to connect via unix sockets (as David Suggests).
I had this issue where the unix socket file was some place else, python was trying to connect to a non-existing socket. Once this was corrected using the unix_socket option, it worked.
Mysql uses sockets when the host is 'localhost' and tcp/ip when the host is anything else. By default Mysql will listen to both - you can disable either sockets or networking in you my.cnf file (see mysql.com for details).
In your case forget about the port=3000 the mysql client lib is not paying any attention to it since you are using localhost and specify the socket as in unix_socket='path_to_socket'.
If you decided to move this script to another machine you will need to change this connect string to use the actual host name or ip address and then you can loose the unix_socket and bring back the port. The default port for mysql is 3306 - you don't need to specify that port but you will need to specify 3000 if that is the port you are using.
As far as I can tell, the python connector can ONLY connect to mysql through a internet socket: unix sockets (the default for the command line client) is not supported.
In the CLI client, when you say "-h localhost", it actually interprets localhost as "Oh, localhost? I'll just connect to the unix socket instead", rather than the internet localhost socket.
Ie, the mysql CLI client is doing something magical, and the Python connector is doing something "consistent, but restrictive".
Choose your poison. (Pun not intended ;) )
Maybe try adding the keyword parameter unix_socket = None to connect()?

Categories

Resources