Классический ответ на этот вопрос заключается в использовании 127.0.0.1
или IP хост или имя хоста вместо «специального названия» localhost
. Из documentation:
[...] соединения на Unix для локального хоста сделаны с использованием файла сокета Unix по умолчанию
И далее:
На Unix, Программы MySQL обрабатывают имя хоста localhost специально, что может отличаться от ожидаемого по сравнению с другими сетевыми ресурсами, основанные программы. Для соединений с localhost программы MySQL пытаются подключиться к локальному серверу с помощью файла сокета Unix. Это происходит, даже если задана опция -port или -P для указания номера порта. Чтобы клиент установил TCP/IP-соединение с локальным сервером, используйте -host или -h, чтобы указать значение имени узла 127.0.0.1 или IP-адрес или имя локального сервера.
Однако этот простой трюк, как представляется, не работать в вашем случае, так что вы должны каким-то образом силу использование сокета TCP. Как вы объяснили это самостоятельно, при вызове mysql
в командной строке вы используете опцию --protocol tcp
.
Как пояснил here, из SQLAlchemy, вы можете передать соответствующие параметры (если таковые имеются) в драйвере либо в качестве опции URL или используя аргумент connect_args
ключевое слово.
Например, используя PyMySQL, на тестовой системе я установки для этой цели (MariaDB 10.0.12, SQLAlchemy 0.9.8 и 0.6.2) PyMySQL я получил следующие результаты:
>>> engine = create_engine(
"mysql+pymysql://sylvain:[email protected]/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:[email protected]/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:[email protected]/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:[email protected]/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:[email protected]/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:[email protected]/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.
настройте туннель ssh, затем укажите локальный mysql в порту туннеля на локальной машине. mysql не будет знать, что он туннелирован, и ssh позаботится о перенаправлении всего, куда он должен идти. –
туннель уже установлен из X.X.X.X: 3306 -> localhost: 3306 Возможно, мне нужно настроить туннель на другой порт, например localhost: 3307? – strevg
@strevg Чтобы уточнить, у вас есть сервер MySQL, работающий на вашем локальном хосте. И второй сервер MySQL, доступный удаленно через SSH-туннель. Оба работают одновременно? Какой сервер связан с каким портом на вашем локальном хосте? –