Как подключить базу данных MySQL с помощью Python+SQLAlchemy удаленно?
Я имею доступ трудность удаленно к MySQL. Я использую SSH-туннель и хочу подключить базу данных MySQL с помощью Python+SQLALchemy.
когда я использую MySQL-client в моей консоли и указываю"
2 ответов
классический ответ на этот вопрос-использовать 127.0.0.1
или IP хоста или хоста вместо "имя" localhost
. От документация:
[...] соединения для Unix localhost в сделаны с использованием файла сокета Unix по умолчанию
и затем:
в Unix программы MySQL обрабатывают имя хоста localhost в особенно, так что, скорее всего, отличается от того, что вы ожидаете по сравнению с другими сетевыми программами. Для соединений с localhost программы MySQL пытаются подключиться к локальному серверу с помощью файла сокета Unix. Это происходит, даже если задан параметр --port или-P для указания номера порта. Чтобы убедиться, что клиент устанавливает TCP/IP-соединение с локальным сервером, используйте --host или-h, чтобы указать значение имени хоста 127.0.0.1 или IP-адрес или имя локального сервер.
однако, этот простой трюк не работает в вашем случае, поэтому вам придется как-то силу использование сокета TCP. Как вы сами объяснили, когда призывали mysql
в командной строке, вы используете .
как пояснил здесь, из SQLAlchemy, вы можете передать соответствующие параметры (если таковые имеются) драйверу либо как параметры URL или С помощью connect_args
ключевое слово аргумент.
>>> 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-соединение (я знаю, что из-за номера порта после имени хоста). С другой стороны:--14-->
>>> 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) просто используя 127.0.0.1 вместо localhost в MySQL SQLAlchemy url работает. Полный url, который я использую именно для этого сценария (туннель с локальным портом 3307):
mysql:/user:passwd@127.0.0.1:3307/
Я использую SQLAlchemy 1.0.5, но я думаю,что это не имеет большого значения...