Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie verbinde ich eine MySQL-Datenbank mit Python+SQLAlchemy aus der Ferne?

Die klassische Antwort auf dieses Problem ist die Verwendung von 127.0.0.1 oder die IP des Hosts oder der Hostname anstelle des "speziellen Namens" localhost . Aus der Dokumentation :

Und später:

Allerdings scheint dieser einfache Trick in Ihrem Fall nicht zu funktionieren, also müssen Sie es irgendwie erzwingen die Verwendung eines TCP-Sockets. Wie Sie es selbst erklärt haben, beim Aufruf von mysql Auf der Kommandozeile verwenden Sie das --protocol tcp Option.

Wie hier erklärt , von SQLAlchemy, können Sie die relevanten Optionen (falls vorhanden) entweder als URL-Optionen oder an Ihren Treiber übergeben mit den connect_args Schlüsselwortargument.

Zum Beispiel mit PyMySQL , auf einem Testsystem, das ich zu diesem Zweck eingerichtet habe (MariaDB 10.0.12, SQLAlchemy 0.9.8 und PyMySQL 0.6.2), habe ich die folgenden Ergebnisse erhalten:

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

Wie Sie bemerkt haben, verwenden beide eine TCP-Verbindung (ich weiß das wegen der Portnummer nach dem Hostnamen). Andererseits:

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

Kein Port nach dem Hostnamen :Dies ist ein UNIX-Socket.