Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como conectar o banco de dados MySQL usando Python + SQLAlchemy remotamente?


A resposta clássica para esse problema é usar 127.0.0.1 ou o IP do host ou o nome do host em vez do "nome especial" localhost . Da documentação :

E depois:

No entanto, esse truque simples não parece funcionar no seu caso, então você precisa forçar de alguma forma o uso de um soquete TCP. Como você mesmo explicou, ao invocar mysql na linha de comando, você usa o --protocol tcp opção.

Conforme explicado aqui , do SQLAlchemy, você pode passar as opções relevantes (se houver) para o seu driver como opções de URL ou usando o connect_args argumento de palavra-chave.

Por exemplo, usando PyMySQL , em um sistema de teste que configurei para esse fim (MariaDB 10.0.12, SQLAlchemy 0.9.8 e PyMySQL 0.6.2) obtive os seguintes resultados:
>>> 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',)]

Como você notou, ambos usarão uma conexão TCP (eu sei disso por causa do número da porta após o nome do host). Por outro lado:
>>> 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',)]

Nenhuma porta após o nome do host :este é um soquete UNIX.