Can't connect to mysql through django - python

I had installed mysql and on python shell import MySQLdb does work. I also changed the settings.py as:
**DATABASE_ENGINE = 'mysql'
DATABASE_NAME = '/home/database/my_db.db'
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''**
but when I test for the connection it fails.
terminal:
>>> from django.db import connection
>>> cursor = connection.cursor()
It gives the error as :
OperationalError: (2002, "Can't connect to local MySQL server through socket '/var/run/mysql' (2)")

Django say its engine should be https://docs.djangoproject.com/en/dev/ref/settings/#engine 'django.db.backends.mysql'
I think database name is the name of the database inside mysql not a path. A path is just for sqlite. Do you have mysql server running?
USER, PASSWORD are required. host defaults to localhost port defualts to 3306.

Are you running a MySQL server? is it on:
localhost (unix domain socket), or
localhost (tcp), or
localhost but not accessible, or
some other host?
also, database name is name as mysql understands it, not a file path.

Related

Python: Using 'Null' for mysql.connector's port argument

I have a mysql database and I fetch it via a domain like www.mydomain-database.com. this domain is given by a company for accessing my database by phpmyadmin. When I browse this domain, it fetches phpmyadmin login page.
I try to connect to this database by the following code:
db = mysql.connector.connect(
host = "www.mydomain-database.com",
user = "root",
passwd = "**",
database = "database",
charset = 'utf8', use_unicode=True
)
When I run this, I get the following exept:
Can't connect to MySQL server on 'https://www.mydomain-database.com:3306' (-2 Name or service not known)
As you can see, connector adds port 3306 to my host; but the url with this port is not valid & it doesn't fetch the phpmyadmin!
So, for canceling that change, I added the port = "" as an argument for my connection but I got another error that mentioned the port must be integer!
Now the question is, how can I remove that port number when connector tries to connect the host?
You have to supply a port. By default MySQL uses port 3306. If your MySQL instance is using a different port, then you can specify that port in the settings.
Do you have access to the MySQL instance?
If so you can try and run:
mysql> SHOW GLOBAL VARIABLES LIKE 'PORT';
to get your port number.
However, your error message refers to server https://
that is not normal, there should not be any reference to https://
Can you check your code in your app and make sure that
host = "www.mydomain-database.com"
and not
host = "https://www.mydomain-database.com"

Connecting to mysql db via ssh with python

I have tried solutions found on other SO questions but none of them have worked for me. I am attempting to pull data from a mysql db running on a remote server by setting up an ssh tunnel. My code is as follows:
server = sshtunnel.SSHTunnelForwarder(
('10.6.41.10', 22),
ssh_username= 'serveruser',
ssh_password= 'serverpw',
remote_bind_address=('127.0.0.1', 3306))
server.start()
print(server.local_bind_port)
cnx = mysql.connector.connect(user='root', password='mysqlpw',
host='127.0.0.1',
database='mydb',
charset='utf8',
use_unicode='FALSE',
port = 3306)
However, when I run this code I receive:
1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
I have also tried adding
local_bind_address = ('0.0.0.0', 3306)
to the sshtunnel setup and instead recieved
Problem setting SSH Forwarder up: Couldn't open tunnel 0.0.0.0:3306 <> 127.0.0.1:3306 might be in use or destination not reachable
I don't fully understand the remote_bind_address and local_bind_address, so my guess is that must be doing something wrong there. I know my username/pw/server info is correct, I am able to ssh into my server via terminal and then use
mysql -h 127.0.0.1 -u root -p
to successfully log into my mysql server. So what do I need to fix to get it running in python? Thanks.
If you don't specify local_bind_address in sshtunnel.SSHTunnelForwarder, the local port is allocated randomly. In that case set port=server.local_bind_port in mysql.connector.connect().
Instead, you can also set local_bind_address=('0.0.0.0', [some port which is not in use]) in sshtunnel.SSHTunnelForwarder. The sshtunnel.HandlerSSHTunnelForwarderError ("Problem setting...") tells you that you can't use local_bind_address=('0.0.0.0', 3306).

How can I use python get connection to MySQL via pubilic IP?

I am trying to use python to get a connection to MySQL,
It is python code is :
import MySQLdb
conn= MySQLdb.connect(
host='public ip',
port = 3306,
user='root',
passwd='123456',
db ='test_schema',
)
so it always give the errors:
_mysql_exceptions.OperationalError: (2003, "Can't connect to MySQL server on 'pubilic ip' (10060)")
Building off AK47's answer
You need to first find the public facing ip address of your machine.
Go to google and search What's my ip address you should get a set of numbers xx.xx.xxxx.xx for example 12.42.111.2
Then in your mysql you need to modify the conf file if linux, ini file if windows
/etc/mysql/my.cnf Unix/OSX systems.
C:\Program Files\MySQL\MySQL Server 5.5\ Windows system
change bind-address to your ip address from google.
Then in AK47's answer replace host='127.0.0.1' to host=<ip from google>
Update your connection parameters to have an actual IP address in the 'host' field
import MySQLdb
conn= MySQLdb.connect(
host='127.0.0.1',
port = 3306,
user='root',
passwd='123456',
db ='test_schema')

How to connect MySQL database using Python+SQLAlchemy remotely?

I am having difficulty accessing MySQL remotely. I use SSH tunnel and want to connect the database MySQL using Python+SQLALchemy.
When i use MySQL-client in my console and specify "ptotocol=TCP", then everything is fine!
I use command:
mysql -h localhost —protocol=TCP -u USER -p
I get access to remote database through SSH-tunnel.
However, when I want to connect to the database using the Python+SQLAchemy I can't find such option like —protocol=TCP
Otherwise, i have only connect to local MySQL Databases.
Tell me please, is there a way to do it using SQLAlchemy.
The classic answer to this issue is to use 127.0.0.1 or the IP of the host or the host name instead of the "special name" localhost. From the documentation:
[...] connections on Unix to localhost are made using a Unix socket file by default
And later:
On Unix, MySQL programs treat the host name localhost specially, in a way that is likely different from what you expect compared to other network-based programs. For connections to localhost, MySQL programs attempt to connect to the local server by using a Unix socket file. This occurs even if a --port or -P option is given to specify a port number. To ensure that the client makes a TCP/IP connection to the local server, use --host or -h to specify a host name value of 127.0.0.1, or the IP address or name of the local server.
However, this simple trick doesn't appear to work in your case, so you have to somehow force the use of a TCP socket. As you explained it yourself, when invoking mysql on the command line, you use the --protocol tcp option.
As explained here, from SQLAlchemy, you can pass the relevant options (if any) to your driver either as URL options or using the connect_args keyword argument.
For example using PyMySQL, on a test system I've setup for that purpose (MariaDB 10.0.12, SQLAlchemy 0.9.8 and PyMySQL 0.6.2) I got the following results:
>>> engine = create_engine(
"mysql+pymysql://sylvain:passwd#localhost/db?host=localhost?port=3306")
# ^^^^^^^^^^^^^^^^^^^^^^^^^^
# Force TCP socket. Notice the two uses of `?`
# Normally URL options should use `?` and `&`
# after that. But that doesn't work here (bug?)
>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost:54164',)]
# Same result by using 127.0.0.1 instead of localhost:
>>> engine = create_engine(
"mysql+pymysql://sylvain:passwd#127.0.0.1/db?host=localhost?port=3306")
>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost:54164',)]
# Alternatively, using connect_args:
>>> engine = create_engine("mysql+pymysql://sylvain:passwd#localhost/db",
connect_args= dict(host='localhost', port=3306))
>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost:54353',)]
As you noticed, both will use a TCP connection (I know that because of the port number after the hostname). On the other hand:
>>> engine = create_engine(
"mysql+pymysql://sylvain:passwd#localhost/db?unix_socket=/path/to/mysql.sock")
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Specify the path to mysql.sock in
# the `unix_socket` option will force
# usage of a UNIX socket
>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost',)]
# Same result by using 127.0.0.1 instead of localhost:
>>> engine = create_engine(
"mysql+pymysql://sylvain:passwd#127.0.0.1/db?unix_socket=/path/to/mysql.sock")
>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost',)]
# Alternatively, using connect_args:
>>> engine = create_engine("mysql+pymysql://sylvain:passwd#localhost/db",
connect_args= dict(unix_socket="/path/to/mysql.sock"))
>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost',)]
No port after the hostname: this is an UNIX socket.
This worked for me:
import pandas as pd
import pymysql
from sqlalchemy import create_engine
cnx = create_engine('mysql+pymysql://<username>:<password>#<host>/<dbname>')
df = pd.read_sql('SELECT * FROM <table_name>', cnx) #read the entire table
Where credentials are added to mysql database like this:
CREATE USER '<username>' IDENTIFIED BY '<password>';
GRANT ALL PRIVILEGES ON *.* TO '<username>' WITH GRANT OPTION;
FLUSH PRIVILEGES;
In my setup (I'm using mysql-python) just using 127.0.0.1 instead of localhost in the MySQL SQLAlchemy url works. The complete url I'm using exactly for that scenario (tunnel with local port 3307) is:
mysql:/user:passwd#127.0.0.1:3307/
I'm using SQLAlchemy 1.0.5, but I guess that doesn't matter too much...
I Tried this to connect with mysql db of xampp server
from sqlalchemy import create_engine
engine = create_engine("mysql+pymysql://usrnme:passwd#hstnme/dbname")
If you are using Python 3.x you can use:
pip install mysql-connector-python
Then:
import sqlalchemy as db
engine = db.create_engine("mysql+mysqlconnector://username:password#hostname:port/dbname")

Is it possible to use Mysql with SqlAlchemy and Flask if my mysql socket isn't in /tmp?

The location for mysql.sock on my system is /usr/local/mysql5/mysqld.sock
thrilllap-2:tmp reuven$ mysqld --print-defaults
mysqld would have been started with the following arguments:
--socket=/usr/local/mysql5/mysqld.sock --port=3306
When I try to use mysql via sqlalchemy from flask, I get:
File "build/bdist.macosx-10.6-intel/egg/MySQLdb/connections.py", line 187, in __init__
sqlalchemy.exc.OperationalError: (OperationalError) (2002, "Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)") None None
The mysql program connects correctly to the database, as does every other mysql client on my system.
My my.cnf has the correct location for the socket
[client]
port = 3306
socket = /usr/local/mysql5/mysqld.sock
[safe_mysqld]
socket = /usr/local/mysql5/mysqld.sock
[mysqld_safe]
socket = /usr/local/mysql5/mysqld.sock
[mysqld]
socket = /usr/local/mysql5/mysqld.sock
port = 3306
The base "SQLAlchemy" library has an option where you can specify the location of the mysql.sock, but this isn't exposed through the sqlalchemy / flask library
http://packages.python.org/Flask-SQLAlchemy/config.html
My questions:
Where does sqlalchemy get the idea that /tmp/mysql.sock is the correct location?
Is there a way to change the default via the Flash-SQLAlchemy connector
You'll have to dig up the exact syntax, but for MySQL I think they use a unix_socket query opt. Something like:
mysql:///dbname?unix_socket=/opt/mysql/mysql.sock'
Should be your connect URI for SQLAlchemy.
Yes! Sean was right
app.config['SQLALCHEMY_DATABASE_URI'] = ''mysql://dayenu:secret.word#localhost/dayenu?unix_socket=/usr/local/mysql5/mysqld.sock
db = SQLAlchemy(app)
works fine! I think this parameter is used by pyodbc, which is what SQLAlchemy uses to talk to mysql, but I couldn't find this parameter anywhere in the pyodbc documentation.
You could create the conexión using
sqlalchemy.create_engine(
mysql_str = sqlalchemy.engine.url.URL(
drivername='mysql+pymysql',
username="db_user",
password="db_pass",
database=db_name,
query={
'unix_socket': '/usr/local/mysql5/mysqld.sock'
}
)
)

Categories