如何使用 Python+SQLAlchemy 远程连接 MySQL 数据库?
How to connect MySQL database using Python+SQLAlchemy remotely?
我无法远程访问 MySQL。我使用 SSH 隧道并想使用 Python+SQLALchemy.
连接数据库 MySQL
当我在我的控制台中使用 MySQL-client 并指定“ptotocol=TCP
”时,一切都很好!
我使用命令:
mysql -h localhost —protocol=TCP -u USER -p
我通过 SSH 隧道访问远程数据库。
但是,当我想使用 Python+SQLAchemy 连接到数据库时,我找不到像 —protocol=TCP
这样的选项
否则,我只能连接到本地 MySQL 数据库。
请告诉我,有没有办法使用 SQLAlchemy 来完成。
这个问题的经典答案是使用 127.0.0.1
或主机的 IP 或 主机名的 "special name" localhost
。来自 documentation:
[...] connections on Unix to localhost are made using a Unix socket file by default
以后:
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.
但是,这个简单的技巧似乎对您的情况不起作用,因此您必须以某种方式强制 使用 TCP 套接字。正如您自己解释的那样,在命令行上调用 mysql
时,您使用 --protocol tcp
选项。
如 here 所述,从 SQLAlchemy 中,您可以将相关选项(如果有的话)作为 URL 选项 或 使用connect_args
关键字参数。
例如,在我为此目的设置的测试系统(MariaDB 10.0.12、SQLAlchemy 0.9.8 和 PyMySQL 0.6.2)上使用 PyMySQL,我得到了以下结果:
>>> 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',)]
正如您所注意到的,两者都将使用 TCP 连接(我知道这是因为主机名后面的端口号)。另一方面:
>>> 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',)]
主机名后没有端口:这是一个 UNIX 套接字。
在我的设置中(我正在使用 mysql-python)只是在 MySQL SQLAlchemy url 中使用 127.0.0.1 而不是本地主机。完整的 url 我正在使用的那个场景(本地端口 3307 的隧道)是:
mysql:/user:passwd@127.0.0.1:3307/
我正在使用 SQLAlchemy 1.0.5,但我想这无关紧要...
这对我有用:
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
将凭据添加到 mysql 数据库的位置如下:
CREATE USER '<username>' IDENTIFIED BY '<password>';
GRANT ALL PRIVILEGES ON *.* TO '<username>' WITH GRANT OPTION;
FLUSH PRIVILEGES;
我试过这个来连接 xampp 服务器的 mysql 数据库
from sqlalchemy import create_engine
engine = create_engine("mysql+pymysql://usrnme:passwd@hstnme/dbname")
我无法远程访问 MySQL。我使用 SSH 隧道并想使用 Python+SQLALchemy.
连接数据库 MySQL当我在我的控制台中使用 MySQL-client 并指定“ptotocol=TCP
”时,一切都很好!
我使用命令:
mysql -h localhost —protocol=TCP -u USER -p
我通过 SSH 隧道访问远程数据库。
但是,当我想使用 Python+SQLAchemy 连接到数据库时,我找不到像 —protocol=TCP
这样的选项
否则,我只能连接到本地 MySQL 数据库。
请告诉我,有没有办法使用 SQLAlchemy 来完成。
这个问题的经典答案是使用 127.0.0.1
或主机的 IP 或 主机名的 "special name" localhost
。来自 documentation:
[...] connections on Unix to localhost are made using a Unix socket file by default
以后:
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.
但是,这个简单的技巧似乎对您的情况不起作用,因此您必须以某种方式强制 使用 TCP 套接字。正如您自己解释的那样,在命令行上调用 mysql
时,您使用 --protocol tcp
选项。
如 here 所述,从 SQLAlchemy 中,您可以将相关选项(如果有的话)作为 URL 选项 或 使用connect_args
关键字参数。
例如,在我为此目的设置的测试系统(MariaDB 10.0.12、SQLAlchemy 0.9.8 和 PyMySQL 0.6.2)上使用 PyMySQL,我得到了以下结果:
>>> 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',)]
正如您所注意到的,两者都将使用 TCP 连接(我知道这是因为主机名后面的端口号)。另一方面:
>>> 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',)]
主机名后没有端口:这是一个 UNIX 套接字。
在我的设置中(我正在使用 mysql-python)只是在 MySQL SQLAlchemy url 中使用 127.0.0.1 而不是本地主机。完整的 url 我正在使用的那个场景(本地端口 3307 的隧道)是:
mysql:/user:passwd@127.0.0.1:3307/
我正在使用 SQLAlchemy 1.0.5,但我想这无关紧要...
这对我有用:
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
将凭据添加到 mysql 数据库的位置如下:
CREATE USER '<username>' IDENTIFIED BY '<password>';
GRANT ALL PRIVILEGES ON *.* TO '<username>' WITH GRANT OPTION;
FLUSH PRIVILEGES;
我试过这个来连接 xampp 服务器的 mysql 数据库
from sqlalchemy import create_engine
engine = create_engine("mysql+pymysql://usrnme:passwd@hstnme/dbname")