I'm using Python 3.5, pymysql 0.7.6 on MacOS X 10.12.
I'm trying to use python to access a MySQL database in a remote server. I have no problems to access from the command line using:
ssh root#XXX.XXX.XXX.XXX
root#XXX.XXX.XXX.XXX's password: my_server_password
and then in the server:
mysql my_database -p
Enter password: my_database_password
And it works and I can do all sort of things with my database. Now, I try to do the same within python, following the documentation or the numerous examples I've found in other posts here:
import pymysql
cnx = pymysql.connect(host='XXX.XXX.XXX.XXX', port='3306', user='root', password='my_server_password', db='my_database')
And it does not work, getting as error:
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'XXX.XXX.XXX.XXX' ([Errno 61] Connection refused)")
The credentials are the correct credentials and I've checked that the port is the correct port, as it is suggested in other posts. I suspect it might be related with the database having also a password, not just the server, but I haven't found any way of including both passwords. Indeed, I'm not sure which password should be included in the connect command, if the server password or the database password. It does not work with neither of them.
So, do you have any suggestion about what might be the issue here or if I'm missing an important bit?
When you run the mysql command, you are doing this in an SSH shell. That is you are connecting to the server running on the remote machine via a localhost connection. That remote server doesn't seem to be set up to allow remote connections to it, only connections from the machine itself.
You'll need to have your python script connect to the MySQL server the same way you are, via SSH. You can open an SSH tunnel to port 3306 on the remote server.
The module I like to use for this purpose is: https://pypi.python.org/pypi/sshtunnel
from sshtunnel import SSHTunnelForwarder
import pymysql
server = SSHTunnelForwarder(
'XXX.XXX.XXX.XXX',
ssh_username='root',
ssh_password='my_server_password',
remote_bind_address=('127.0.0.1', 3306)
)
server.start()
cnx = pymysql.connect(
host='127.0.0.1',
port=server.local_bind_port,
user='root',
password='my_database_password',
db='my_database'
)
# Make sure to call server.stop() when you want to disconnect
# after calling cnx.close()
Based on the information given, I would suggest you try the following:
Ensure the MySQL bind address is "0.0.0.0". You can do this by editing /etc/mysql/my.cnf and checking the bind-address option is set to "0.0.0.0"
Make sure the port is open from your remote machine. Install "nmap" then use nmap -sS -O -p3306 <public-server-ip>. If see something like 3306/mysql open all good. If not, you need to ensure your firewall isn't blocking that port.
As Rocket Hazmat suggests you probably will want to use an SSH tunnel to reduce the risks of exposing MySQL port directly as data is probably sent in the clear. If you just need to test your code locally before deploying to the server you can use the following command before you run your Python code: ssh -f user#serverip -L 3306:127.0.0.1:3306 -N. In this case you don't need to complete step one and two.
working code
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import pymysql
import sshtunnel
from sshtunnel import SSHTunnelForwarder
server = SSHTunnelForwarder(
('xx.xx.xx.xx', 22),
ssh_username='deploy',
ssh_pkey='~/.ssh/id_rsa',
remote_bind_address=('127.0.0.1', 3306)
)
server.start()
con = pymysql.connect(host='127.0.0.1', user='root', passwd='mysql', db='backoffice_demo', port=server.local_bind_port)
with con:
cur = con.cursor()
cur.execute("SELECT VERSION()")
version = cur.fetchone()
print("Database version: {}".format(version[0]))
Related
I am relatively new to this topic. I try to build a webapp using flask. The webapp uses data from a postgresql database which is running local (Mac OS Monterey 12.2.1).
My application uses a python code which accesses data from the database by connecting to the database with psycopg2:
con = psycopg2.connect(
host = "192.168.178.43"
database = self.database,
port = "5432",
user = "user",
password = "password")
I already added the relevant entries to the "pg_hba.conf" file and to the "postgresql.conf" file to the needed configurations for an access in my home network. But i still got an error when starting the container. The app runs perfect outside the container. I think I miss some important steps to complete a successful connection.
This error is the following
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 5432?
I'm connecting to MySQL db through SSH on server. I managed to do it through MySql workbench and through system shell, which means passwords, username and ip are correct and allowed.
Now I'm trying to connect through Python. I'm using sshtunnel package with the same settings as in workbench (in shell all was default) - mysql port 3306, ssh port 22, mysql hostname 127.0.0.1 and it connects me.
When I'm trying to connect through connector to db I'm getting:
mysql.connector.errors.ProgrammingError: 1045 (28000): Access denied
for user 'myusername'#'localhost' (using password: YES).
I also tried to connect directly through shell with python using:
os.system("mysql -u myusername -p")
and I got:
ERROR 1045 (28000): Access denied for user 'myusername'#'localhost'
(using password: YES)
I checked here:
Can't access MySQL through MySQL Workbench or HeidiSQL, but can access through shell
Accessing MySQL from Python 3: Access denied for user
And many more, but I found nothing helpful.
My Python version is 3.6.8, MySql version is 5.7.31.
What other thing may differ between shell accessed by python and the normal Unix one? Or access got by workbench?
Edit:
Requested code. All of the three connections gave exactly the same output.
with sshtunnel.SSHTunnelForwarder(
(ssh_host, ssh_port),
ssh_username=ssh_username,
ssh_password=ssh_password,
remote_bind_address=('localhost', mysql_port)) as tunnel:
# conn = mysql.connector.connect(**mysql_config)
conn = MySQLdb.connect(host="localhost",
user="myusername", passwd="password", db="mydb")
print(conn)
# print(os.system("mysql -u myusername -p"))
I managed to connect with:
tunnel = sshtunnel.SSHTunnelForwarder((ssh_host, 22), ssh_password=ssh_password, ssh_username=ssh_username,
remote_bind_address=('localhost', 3306))
tunnel.start()
Apparently the difference was to keep the tunnel open instead of using 'with' statement, though I don't understand what actually happened and I'd appreciate explanation.
I want to connect MongoDB server with python.
I have connected it on the terminal of MacOS and I run some MongoDB queries. (as described this link http://ghtorrent.org/raw.html)
sshtunnel: ssh -L 27017:dutihr.st.ewi.tudelft.nl:27017 ghtorrent#dutihr.st.ewi.tudelft.nl
connect to mongo: mongo -u ghtorrentro -p ghtorrentro github
what are the parameters of the above "ssh" and "mongo" commands?
How to connect remote mongodb with pymongo and
Can I connect to GHTorrent MySQL/Mongodb database through ssh?
I see these question, I tried to write my code according to these answers but it's not working.
import pymongo
import sshtunnel
from sshtunnel import SSHTunnelForwarder
import paramiko
mypkey = paramiko.RSAKey.from_private_key_file("/Users/aaa/.ssh/id_rsa","xxx") #username(aaa) and password(xxx)
server = SSHTunnelForwarder(
('dutihr.st.ewi.tudelft.nl', 22),
ssh_username="",
ssh_pkey=mypkey,
ssh_private_key_password="xxx", #my password for key
remote_bind_address=('0.0.0.0',27017))
server.start()
how can I find the right parameters of these codes? how can I connect this MongoDB server? It give this error;
2019-10-31 00:11:51,304| ERROR | Secsh channel 49 open FAILED: open failed: Administratively prohibited
2019-10-31 00:11:51,305| ERROR | Could not establish connection from ('127.0.0.1', 51634) to remote side of the tunnel
I think do not understand properly how does sqlalchemy works, I have tried to connect to postgresql running on some cloud server from my local computer:
db = create_engine('postgresql://ubuntu#172.23.160.212:5432/dbname')
but that causes the error:
Is the server running on host "172.23.160.212" and accepting
TCP/IP connections on port 5432?
I have checked the port and host also exists.
I thought I should connect to the host using ssh first:
with SSHTunnelForwarder((172.23.160.212, 22), ssh_username='ubuntu', remote_bind_address=(127.0.0.1, 3306)) as server:
db = create_engine('postgresql://postgres#127.0.0.1:5432/dbname')
But that did not help.
I have solved the problem partially,
If one opens ssh connection in bash (ssh ubuntu#172.23.160.212 -L 5432:localhost:5432 -N -n -f), then one can open db through python:
db = create_engine('postgresql://tissuemaps#localhost:5432/dbname')
If I understand correctly, the connection to postgres directly should also have worked, and why it does not, I do not know.
I think the problem is TCP connection is not enabled and have to modify your pg_hba.conf file to allow the connection. Add lines in the config file to allow connection
host all all 0.0.0.0/0 md5
host all all ::/0 md5
Apart from that you can also check postgresql.conf (/etc/postgresql/9.3/main/postgresql.conf) to check other postgres configs are what you expect like port number etc. Also add below line in config file to accept all the connections
listen_addresses = '*'
You need to restart the postgres service for the changes to be picked up
sudo service postgresql restart
https://www.postgresql.org/docs/9.1/static/auth-pg-hba-conf.html
https://www.postgresql.org/docs/9.1/static/runtime-config-connection.html
I am trying to connect MySQL by using ip which I got from PhpMyAdmin using python. But I face Operational Error(2003, "Can't connect to MySQL server on '127.3.138.130' (111)")
I know how to use mysql to connect to localhost
I am following this tutorial
I have written following lines of code in python
I am using ubuntu terminal to run python code and I do have mysql-server installed on my laptop.
import MySQLdb
db = MySQLdb.connect('127.3.138.130','my_username','my_password','my_db_name')
So what the problem is ? how to solve this problem ,please explain me in very simple manner. Thanks!
Make sure the server listens to outside requests. To do this go to /etc/mysql/my.cnf on the server and edit:
bind-address = 127.0.0.1
To:
bind-address = 0.0.0.0
You may need to use sudo when editing the file.
You will need to restart the server after changing the configuration:
sudo service mysql restart
You can also see what port is the server listening on (the default being 3306) in /etc/mysql/my.cnf. Just look for a line that says:
port = 3306
Make sure you're connecting to through same port, this is how you can specify a port:
db = MySQLdb.connect(
host = '127.3.138.130',
user = 'my_username',
passwd = 'my_password',
db = 'my_db_name',
port = 3306 # should be same as in /etc/mysql/my.cnf on server.
)
use 'pymysql' lib...it may help u....
import pymysql
conn = pymysql.connect(host=''127.3.138.130', port=3306, user='root', passwd='password', db='dbname')