如何使用Python+SQLAlchemy远程连接MySQL数据库?

mctunoxg  于 2023-02-03  发布在  Mysql
关注(0)|答案(5)|浏览(108)

我在远程访问MySQL时遇到困难。我使用SSH隧道,想使用Python+SQLALchemy连接数据库MySQL。
当我在控制台中使用MySQL客户端并指定“ptotocol=TCP“时,一切都很好!

mysql -h localhost —protocol=TCP -u USER -p

我通过SSH隧道访问远程数据库。
但是,当我想用Python+SQLAchemy连接到数据库时,我找不到—protocol=TCP这样的选项。否则,我只能连接到本地MySQL数据库。请告诉我,有没有办法用SQLAlchemy来连接。

blpfk2vs

blpfk2vs1#

这个问题的经典答案是使用127.0.0.1或 * 主机的IP * 或 * 主机名 *,而不是"特殊名称" localhost
[...]默认情况下,Unix上到 * localhost * 的连接是使用Unix套接字文件建立的
后来:

    • 在Unix上,MySQL程序对主机名 * localhost * 进行特殊处理**,与其他基于网络的程序相比,处理方式可能与您预期的不同。MySQL程序尝试使用Unix套接字文件连接到本地服务器。即使使用--port或-P选项指定端口号,也会发生这种情况。要确保客户端使用TCP/本地服务器的IP连接,请使用--host或-h指定主机名值www.example.com,或本地服务器的IP地址或名称。127.0.0.1, or the IP address or name of the local server.

然而,这个简单的技巧似乎在您的情况下不起作用,因此您必须以某种方式强制使用TCP套接字,正如您自己解释的那样,当在命令行上调用mysql时,您使用--protocol tcp选项。
正如这里所解释的,从SQLAlchemy,您可以将相关选项(如果有的话)作为URL选项 * 或使用connect_args关键字参数的 * 传递给驱动程序。
例如,使用 * PyMySQL *,在我为此目的设置的测试系统(MariaDB 10.0.12、SQLAlchemy 0.9.8和PyMySQL 0.6.2)上,我得到了以下结果:

>>> 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',)]
  • hostname * 后面没有端口:这是UNIX套接字。
u0sqgete

u0sqgete2#

这对我很有效:

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;
qnakjoqk

qnakjoqk3#

在我的设置中(我使用的是mysql-python),只需127.0.0.1在MySQL SQLAlchemy url中使用www.example.com而不是localhost就可以了。我在该场景中使用的完整url(使用本地端口3307的隧道)是:

mysql:/user:passwd@127.0.0.1:3307/

我使用的是SQLAlchemy 1.0.5,但我想这并不重要...

dwthyt8l

dwthyt8l4#

我尝试使用此方法连接xampp服务器的mysql数据库

from sqlalchemy import create_engine

engine = create_engine("mysql+pymysql://usrnme:passwd@hstnme/dbname")
pxiryf3j

pxiryf3j5#

如果你使用Python 3.x,你可以使用:

pip install mysql-connector-python

然后:

import sqlalchemy as db
engine = db.create_engine("mysql+mysqlconnector://username:password@hostname/dbname")

相关问题