Repository: modin-project/modin

Issue:
FEAT: Pass connection objects to read_sql
Comes from https://stackoverflow.com/questions/68999218/how-to-pass-the-sqlalchemyconnection-string-for-oracle-modin-read-sql.


Discussion:
cc @amyskov 
Currently modin `read_sql` doesn't support SQLAlchemy or another object connectables, so `con` parameter should be passed as string. Connection string looks correct, so, i think, we need more details about this case (can reproducer be provided or does it work on `pandas.read_sql`?).
I'm having the same issue as the poster. In my case, pandas.read_sql works and when I try using modin.pandas with pd.read_sql, I get the following message:

"UserWarning: To use parallel implementation of `read_sql`, pass the sqlalchemyconnection string instead of <class 'sqlalchemy.engine.base.Connection'>.
UserWarning: Parameters provided defaulting to pandas implementation."

Can I have an example of how to pass the sqlalchemyconnection string to pd.read_sql?
Hi @OBINJAWED 

It looks that it works as string and without importing sqlalchemy
```
import modin.pandas as pd

from distributed import Client
client = Client()

connection = 'mariadb+pymysql://user:password@host:port/databasename'

df = pd.read_sql(your_query_as_string,connection,index_col=None, coerce_float=True, params=None, parse_dates=None, chunksize=None)
```

I tested it with fallback (like pandas) and with modin.pandas on 3 GB table, and there is a huge difference in table reading time, with fallback it takes 15 min, and with modin.pandas more less 1 minute

Regards

Resolving patch:
diff --git a/modin/core/io/sql/sql_dispatcher.py b/modin/core/io/sql/sql_dispatcher.py
--- a/modin/core/io/sql/sql_dispatcher.py
+++ b/modin/core/io/sql/sql_dispatcher.py
@@ -57,8 +57,8 @@ def _read(cls, sql, con, index_col=None, **kwargs):
         BaseQueryCompiler
             Query compiler with imported data for further processing.
         """
-        connection_is_modin_db_connection = isinstance(con, ModinDatabaseConnection)
-        if not (connection_is_modin_db_connection or isinstance(con, str)):
+        is_modin_db_connection = isinstance(con, ModinDatabaseConnection)
+        if not (is_modin_db_connection or isinstance(con, str)):
             warnings.warn(
                 "To use parallel implementation of `read_sql`, pass either "
                 "the SQL connection string or a ModinDatabaseConnection "
@@ -69,9 +69,7 @@ def _read(cls, sql, con, index_col=None, **kwargs):
             )
             return cls.single_worker_read(sql, con=con, index_col=index_col, **kwargs)
         row_cnt_query = "SELECT COUNT(*) FROM ({}) as foo".format(sql)
-        connection_for_pandas = (
-            con.get_connection() if connection_is_modin_db_connection else con
-        )
+        connection_for_pandas = con.get_connection() if is_modin_db_connection else con
         row_cnt = pandas.read_sql(row_cnt_query, connection_for_pandas).squeeze()
         cols_names_df = pandas.read_sql(
             "SELECT * FROM ({}) as foo LIMIT 0".format(sql),
diff --git a/modin/db_conn.py b/modin/db_conn.py
--- a/modin/db_conn.py
+++ b/modin/db_conn.py
@@ -19,8 +19,8 @@
 connection directly to `read_sql`, the open connection is not pickleable
 in Modin, so each worker must open its own connection.
 `ModinDatabaseConnection` saves the arguments that would normally be used to
-make a db connection. It can make and provide the a connection whenever the
-Modin driver or a worker wants one.
+make a db connection. It can make and provide a connection whenever the Modin
+driver or a worker wants one.
 """
 
 _PSYCOPG_LIB_NAME = "psycopg2"


Test patch: