Mysql
 sql >> Database >  >> RDS >> Mysql

Come connettere il database MySQL usando Python+SQLAlchemy da remoto?

La classica risposta a questo problema è usare 127.0.0.1 o l'IP dell'host o il nome host invece del "nome speciale" localhost . Dalla documentazione :

E dopo:

Tuttavia, questo semplice trucco non sembra funzionare nel tuo caso, quindi devi in ​​qualche modo forzare l'uso di un socket TCP. Come l'hai spiegato tu stesso, quando invochi mysql sulla riga di comando, usi il --protocol tcp opzione.

Come spiegato qui , da SQLAlchemy, puoi passare le opzioni pertinenti (se presenti) al tuo driver come opzioni URL o utilizzando connect_args argomento della parola chiave.

Ad esempio usando PyMySQL , su un sistema di test che ho impostato a tale scopo (MariaDB 10.0.12, SQLAlchemy 0.9.8 e PyMySQL 0.6.2) ho ottenuto i seguenti risultati:

>>> 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',)]

Come hai notato, entrambi utilizzeranno una connessione TCP (lo so a causa del numero di porta dopo il nome host). D'altra parte:

>>> 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',)]

Nessuna porta dopo il nome host :questo è un socket UNIX.