Repository: modin-project/modin

Issue:
Rename `read_pickle_distributed/to_pickle_distributed` to ` read_pickle_glob/to_pickle_glob`
For consistency with other functions like `read_csv_glob` and `read_parquet_glob`.

Discussion:

Patch:
diff --git a/docs/flow/modin/experimental/pandas.rst b/docs/flow/modin/experimental/pandas.rst
index 759b8db1..5f26c84d 100644
--- a/docs/flow/modin/experimental/pandas.rst
+++ b/docs/flow/modin/experimental/pandas.rst
@@ -12,11 +12,11 @@ Experimental API Reference
 .. autofunction:: read_sql
 .. autofunction:: read_csv_glob
 .. autofunction:: read_custom_text
-.. autofunction:: read_pickle_distributed
+.. autofunction:: read_pickle_glob
 .. autofunction:: read_parquet_glob
 .. autofunction:: read_json_glob
 .. autofunction:: read_xml_glob
-.. automethod:: modin.pandas.DataFrame.modin::to_pickle_distributed
+.. automethod:: modin.pandas.DataFrame.modin::to_pickle_glob
 .. automethod:: modin.pandas.DataFrame.modin::to_parquet_glob
 .. automethod:: modin.pandas.DataFrame.modin::to_json_glob
 .. automethod:: modin.pandas.DataFrame.modin::to_xml_glob
diff --git a/docs/supported_apis/dataframe_supported.rst b/docs/supported_apis/dataframe_supported.rst
index 2b3789fc..11a1415a 100644
--- a/docs/supported_apis/dataframe_supported.rst
+++ b/docs/supported_apis/dataframe_supported.rst
@@ -433,7 +433,7 @@ default to pandas.
 | ``to_period``              | `to_period`_              | D                      |                                                    |
 +----------------------------+---------------------------+------------------------+----------------------------------------------------+
 | ``to_pickle``              | `to_pickle`_              | D                      | Experimental implementation:                       |
-|                            |                           |                        | DataFrame.modin.to_pickle_distributed              |
+|                            |                           |                        | DataFrame.modin.to_pickle_glob                     |
 +----------------------------+---------------------------+------------------------+----------------------------------------------------+
 | ``to_records``             | `to_records`_             | D                      |                                                    |
 +----------------------------+---------------------------+------------------------+----------------------------------------------------+
diff --git a/docs/supported_apis/io_supported.rst b/docs/supported_apis/io_supported.rst
index 92c6f88e..a44adb71 100644
--- a/docs/supported_apis/io_supported.rst
+++ b/docs/supported_apis/io_supported.rst
@@ -68,7 +68,7 @@ default to pandas.
 | `read_sas`_       | D                               |                                                        |
 +-------------------+---------------------------------+--------------------------------------------------------+
 | `read_pickle`_    | D                               | Experimental implementation:                           |
-|                   |                                 | read_pickle_distributed                                |
+|                   |                                 | read_pickle_glob                                       |
 +-------------------+---------------------------------+--------------------------------------------------------+
 | `read_sql`_       | Y                               |                                                        |
 +-------------------+---------------------------------+--------------------------------------------------------+
diff --git a/docs/usage_guide/advanced_usage/index.rst b/docs/usage_guide/advanced_usage/index.rst
index 4f9cd402..3ca05040 100644
--- a/docs/usage_guide/advanced_usage/index.rst
+++ b/docs/usage_guide/advanced_usage/index.rst
@@ -41,11 +41,11 @@ Modin also supports these experimental APIs on top of pandas that are under acti
 - :py:func:`~modin.experimental.pandas.read_csv_glob` -- read multiple files in a directory
 - :py:func:`~modin.experimental.pandas.read_sql` -- add optional parameters for the database connection
 - :py:func:`~modin.experimental.pandas.read_custom_text` -- read custom text data from file
-- :py:func:`~modin.experimental.pandas.read_pickle_distributed`  -- read multiple pickle files in a directory
+- :py:func:`~modin.experimental.pandas.read_pickle_glob`  -- read multiple pickle files in a directory
 - :py:func:`~modin.experimental.pandas.read_parquet_glob`  -- read multiple parquet files in a directory
 - :py:func:`~modin.experimental.pandas.read_json_glob`  -- read multiple json files in a directory
 - :py:func:`~modin.experimental.pandas.read_xml_glob`  -- read multiple xml files in a directory
-- :py:meth:`~modin.pandas.DataFrame.modin.to_pickle_distributed` -- write to multiple pickle files in a directory
+- :py:meth:`~modin.pandas.DataFrame.modin.to_pickle_glob` -- write to multiple pickle files in a directory
 - :py:meth:`~modin.pandas.DataFrame.modin.to_parquet_glob` -- write to multiple parquet files in a directory
 - :py:meth:`~modin.pandas.DataFrame.modin.to_json_glob` -- write to multiple json files in a directory
 - :py:meth:`~modin.pandas.DataFrame.modin.to_xml_glob` -- write to multiple xml files in a directory
diff --git a/modin/core/execution/dask/implementations/pandas_on_dask/io/io.py b/modin/core/execution/dask/implementations/pandas_on_dask/io/io.py
index e1780833..b0b5b482 100644
--- a/modin/core/execution/dask/implementations/pandas_on_dask/io/io.py
+++ b/modin/core/execution/dask/implementations/pandas_on_dask/io/io.py
@@ -111,10 +111,10 @@ class PandasOnDaskIO(BaseIO):
         ExperimentalGlobDispatcher,
         build_args={**build_args, "base_write": BaseIO.to_xml},
     )
-    read_pickle_distributed = __make_read(
+    read_pickle_glob = __make_read(
         ExperimentalPandasPickleParser, ExperimentalGlobDispatcher
     )
-    to_pickle_distributed = __make_write(
+    to_pickle_glob = __make_write(
         ExperimentalGlobDispatcher,
         build_args={**build_args, "base_write": BaseIO.to_pickle},
     )
diff --git a/modin/core/execution/dispatching/factories/dispatcher.py b/modin/core/execution/dispatching/factories/dispatcher.py
index 195c62b8..f8ff035f 100644
--- a/modin/core/execution/dispatching/factories/dispatcher.py
+++ b/modin/core/execution/dispatching/factories/dispatcher.py
@@ -197,9 +197,9 @@ class FactoryDispatcher(object):
         return cls.get_factory()._read_csv_glob(**kwargs)
 
     @classmethod
-    @_inherit_docstrings(factories.PandasOnRayFactory._read_pickle_distributed)
-    def read_pickle_distributed(cls, **kwargs):
-        return cls.get_factory()._read_pickle_distributed(**kwargs)
+    @_inherit_docstrings(factories.PandasOnRayFactory._read_pickle_glob)
+    def read_pickle_glob(cls, **kwargs):
+        return cls.get_factory()._read_pickle_glob(**kwargs)
 
     @classmethod
     @_inherit_docstrings(factories.BaseFactory._read_json)
@@ -292,9 +292,9 @@ class FactoryDispatcher(object):
         return cls.get_factory()._to_pickle(*args, **kwargs)
 
     @classmethod
-    @_inherit_docstrings(factories.PandasOnRayFactory._to_pickle_distributed)
-    def to_pickle_distributed(cls, *args, **kwargs):
-        return cls.get_factory()._to_pickle_distributed(*args, **kwargs)
+    @_inherit_docstrings(factories.PandasOnRayFactory._to_pickle_glob)
+    def to_pickle_glob(cls, *args, **kwargs):
+        return cls.get_factory()._to_pickle_glob(*args, **kwargs)
 
     @classmethod
     @_inherit_docstrings(factories.PandasOnRayFactory._read_parquet_glob)
diff --git a/modin/core/execution/dispatching/factories/factories.py b/modin/core/execution/dispatching/factories/factories.py
index 4f50995d..ee0c96f1 100644
--- a/modin/core/execution/dispatching/factories/factories.py
+++ b/modin/core/execution/dispatching/factories/factories.py
@@ -476,13 +476,13 @@ class BaseFactory(object):
         source="Pickle files",
         params=_doc_io_method_kwargs_params,
     )
-    def _read_pickle_distributed(cls, **kwargs):
+    def _read_pickle_glob(cls, **kwargs):
         current_execution = get_current_execution()
         if current_execution not in supported_executions:
             raise NotImplementedError(
-                f"`_read_pickle_distributed()` is not implemented for {current_execution} execution."
+                f"`_read_pickle_glob()` is not implemented for {current_execution} execution."
             )
-        return cls.io_cls.read_pickle_distributed(**kwargs)
+        return cls.io_cls.read_pickle_glob(**kwargs)
 
     @classmethod
     @doc(
@@ -526,7 +526,7 @@ class BaseFactory(object):
         return cls.io_cls.read_custom_text(**kwargs)
 
     @classmethod
-    def _to_pickle_distributed(cls, *args, **kwargs):
+    def _to_pickle_glob(cls, *args, **kwargs):
         """
         Distributed pickle query compiler object.
 
@@ -540,9 +540,9 @@ class BaseFactory(object):
         current_execution = get_current_execution()
         if current_execution not in supported_executions:
             raise NotImplementedError(
-                f"`_to_pickle_distributed()` is not implemented for {current_execution} execution."
+                f"`_to_pickle_glob()` is not implemented for {current_execution} execution."
             )
-        return cls.io_cls.to_pickle_distributed(*args, **kwargs)
+        return cls.io_cls.to_pickle_glob(*args, **kwargs)
 
     @classmethod
     @doc(
diff --git a/modin/core/execution/ray/implementations/pandas_on_ray/io/io.py b/modin/core/execution/ray/implementations/pandas_on_ray/io/io.py
index 1cdfb929..3839bd62 100644
--- a/modin/core/execution/ray/implementations/pandas_on_ray/io/io.py
+++ b/modin/core/execution/ray/implementations/pandas_on_ray/io/io.py
@@ -113,10 +113,10 @@ class PandasOnRayIO(RayIO):
         ExperimentalGlobDispatcher,
         build_args={**build_args, "base_write": RayIO.to_xml},
     )
-    read_pickle_distributed = __make_read(
+    read_pickle_glob = __make_read(
         ExperimentalPandasPickleParser, ExperimentalGlobDispatcher
     )
-    to_pickle_distributed = __make_write(
+    to_pickle_glob = __make_write(
         ExperimentalGlobDispatcher,
         build_args={**build_args, "base_write": RayIO.to_pickle},
     )
diff --git a/modin/core/execution/unidist/implementations/pandas_on_unidist/io/io.py b/modin/core/execution/unidist/implementations/pandas_on_unidist/io/io.py
index 1ac29ff9..c5bc772a 100644
--- a/modin/core/execution/unidist/implementations/pandas_on_unidist/io/io.py
+++ b/modin/core/execution/unidist/implementations/pandas_on_unidist/io/io.py
@@ -113,10 +113,10 @@ class PandasOnUnidistIO(UnidistIO):
         ExperimentalGlobDispatcher,
         build_args={**build_args, "base_write": UnidistIO.to_xml},
     )
-    read_pickle_distributed = __make_read(
+    read_pickle_glob = __make_read(
         ExperimentalPandasPickleParser, ExperimentalGlobDispatcher
     )
-    to_pickle_distributed = __make_write(
+    to_pickle_glob = __make_write(
         ExperimentalGlobDispatcher,
         build_args={**build_args, "base_write": UnidistIO.to_pickle},
     )
diff --git a/modin/core/io/sql/sql_dispatcher.py b/modin/core/io/sql/sql_dispatcher.py
index 63e464fe..c32afc12 100644
--- a/modin/core/io/sql/sql_dispatcher.py
+++ b/modin/core/io/sql/sql_dispatcher.py
@@ -32,6 +32,17 @@ from modin.db_conn import ModinDatabaseConnection
 class SQLDispatcher(FileDispatcher):
     """Class handles utils for reading SQL queries or database tables."""
 
+    @classmethod
+    def _is_supported_sqlalchemy_object(cls, obj):  # noqa: GL08
+        supported = None
+        try:
+            import sqlalchemy as sa
+
+            supported = isinstance(obj, (sa.engine.Engine, sa.engine.Connection))
+        except ImportError:
+            supported = False
+        return supported
+
     @classmethod
     def _read(cls, sql, con, index_col=None, **kwargs):
         """
@@ -55,6 +66,12 @@ class SQLDispatcher(FileDispatcher):
         """
         if isinstance(con, str):
             con = ModinDatabaseConnection("sqlalchemy", con)
+
+        if cls._is_supported_sqlalchemy_object(con):
+            con = ModinDatabaseConnection(
+                "sqlalchemy", con.engine.url.render_as_string(hide_password=False)
+            )
+
         if not isinstance(con, ModinDatabaseConnection):
             return cls.single_worker_read(
                 sql,
@@ -62,7 +79,7 @@ class SQLDispatcher(FileDispatcher):
                 index_col=index_col,
                 read_sql_engine=ReadSqlEngine.get(),
                 reason="To use the parallel implementation of `read_sql`, pass either "
-                + "the SQL connection string or a ModinDatabaseConnection "
+                + "a SQLAlchemy connectable, the SQL connection string, or a ModinDatabaseConnection "
                 + "with the arguments required to make a connection, instead "
                 + f"of {type(con)}. For documentation on the ModinDatabaseConnection, see "
                 + "https://modin.readthedocs.io/en/latest/supported_apis/io_supported.html#connecting-to-a-database-for-read-sql",
@@ -111,17 +128,6 @@ class SQLDispatcher(FileDispatcher):
         new_frame.synchronize_labels(axis=0)
         return cls.query_compiler_cls(new_frame)
 
-    @classmethod
-    def _is_supported_sqlalchemy_object(cls, obj):  # noqa: GL08
-        supported = None
-        try:
-            import sqlalchemy as sa
-
-            supported = isinstance(obj, (sa.engine.Engine, sa.engine.Connection))
-        except ImportError:
-            supported = False
-        return supported
-
     @classmethod
     def write(cls, qc, **kwargs):
         """
diff --git a/modin/experimental/pandas/__init__.py b/modin/experimental/pandas/__init__.py
index 19573399..0825a5bb 100644
--- a/modin/experimental/pandas/__init__.py
+++ b/modin/experimental/pandas/__init__.py
@@ -33,13 +33,21 @@ Examples
 """
 
 from modin.pandas import *  # noqa F401, F403
+from modin.utils import func_from_deprecated_location
 
 from .io import (  # noqa F401
     read_csv_glob,
     read_custom_text,
     read_json_glob,
     read_parquet_glob,
-    read_pickle_distributed,
+    read_pickle_glob,
     read_sql,
     read_xml_glob,
 )
+
+read_pickle_distributed = func_from_deprecated_location(
+    "read_pickle_glob",
+    "modin.experimental.pandas.io",
+    "`modin.experimental.pandas.read_pickle_distributed` is deprecated and will be removed in a future version. "
+    + "Please use `modin.experimental.pandas.to_pickle_glob` instead.",
+)
diff --git a/modin/experimental/pandas/io.py b/modin/experimental/pandas/io.py
index 7dc19ac4..0122f303 100644
--- a/modin/experimental/pandas/io.py
+++ b/modin/experimental/pandas/io.py
@@ -303,7 +303,7 @@ read_csv_glob = _make_parser_func(sep=",", funcname="read_csv_glob")
 
 
 @expanduser_path_arg("filepath_or_buffer")
-def read_pickle_distributed(
+def read_pickle_glob(
     filepath_or_buffer,
     compression: Optional[str] = "infer",
     storage_options: StorageOptions = None,
@@ -313,7 +313,7 @@ def read_pickle_distributed(
 
     This experimental feature provides parallel reading from multiple pickle files which are
     defined by glob pattern. The files must contain parts of one dataframe, which can be
-    obtained, for example, by `DataFrame.modin.to_pickle_distributed` function.
+    obtained, for example, by `DataFrame.modin.to_pickle_glob` function.
 
     Parameters
     ----------
@@ -344,11 +344,11 @@ def read_pickle_distributed(
 
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    return DataFrame(query_compiler=FactoryDispatcher.read_pickle_distributed(**kwargs))
+    return DataFrame(query_compiler=FactoryDispatcher.read_pickle_glob(**kwargs))
 
 
 @expanduser_path_arg("filepath_or_buffer")
-def to_pickle_distributed(
+def to_pickle_glob(
     self,
     filepath_or_buffer,
     compression: CompressionOptions = "infer",
@@ -392,7 +392,7 @@ def to_pickle_distributed(
 
     if isinstance(self, DataFrame):
         obj = self._query_compiler
-    FactoryDispatcher.to_pickle_distributed(
+    FactoryDispatcher.to_pickle_glob(
         obj,
         filepath_or_buffer=filepath_or_buffer,
         compression=compression,
diff --git a/modin/pandas/accessor.py b/modin/pandas/accessor.py
index 0eb9c20c..623293e7 100644
--- a/modin/pandas/accessor.py
+++ b/modin/pandas/accessor.py
@@ -22,6 +22,7 @@ CachedAccessor implements API of pandas.core.accessor.CachedAccessor
 """
 
 import pickle
+import warnings
 
 import pandas
 from pandas._typing import CompressionOptions, StorageOptions
@@ -209,7 +210,7 @@ class ExperimentalFunctions:
     def __init__(self, data):
         self._data = data
 
-    def to_pickle_distributed(
+    def to_pickle_glob(
         self,
         filepath_or_buffer,
         compression: CompressionOptions = "infer",
@@ -248,9 +249,9 @@ class ExperimentalFunctions:
             this argument with a non-fsspec URL. See the fsspec and backend storage
             implementation docs for the set of allowed keys and values.
         """
-        from modin.experimental.pandas.io import to_pickle_distributed
+        from modin.experimental.pandas.io import to_pickle_glob
 
-        to_pickle_distributed(
+        to_pickle_glob(
             self._data,
             filepath_or_buffer=filepath_or_buffer,
             compression=compression,
@@ -258,6 +259,22 @@ class ExperimentalFunctions:
             storage_options=storage_options,
         )
 
+    def to_pickle_distributed(
+        self,
+        filepath_or_buffer,
+        compression: CompressionOptions = "infer",
+        protocol: int = pickle.HIGHEST_PROTOCOL,
+        storage_options: StorageOptions = None,
+    ) -> None:  # noqa
+        warnings.warn(
+            "`DataFrame.modin.to_pickle_distributed` is deprecated and will be removed in a future version. "
+            + "Please use `DataFrame.modin.to_pickle_glob` instead.",
+            category=FutureWarning,
+        )
+        return self.to_pickle_glob(
+            filepath_or_buffer, compression, protocol, storage_options
+        )
+
     def to_parquet_glob(
         self,
         path,


Test patch:
diff --git a/modin/experimental/pandas/test/test_io_exp.py b/modin/experimental/pandas/test/test_io_exp.py
index cbbe62e7..ed091dee 100644
--- a/modin/experimental/pandas/test/test_io_exp.py
+++ b/modin/experimental/pandas/test/test_io_exp.py
@@ -249,7 +249,11 @@ def test_read_multiple_csv_s3_storage_opts(
 @pytest.mark.parametrize(
     "filename", ["test_default_to_pickle.pkl", "test_to_pickle*.pkl"]
 )
-def test_distributed_pickling(tmp_path, filename, compression, pathlike):
+@pytest.mark.parametrize("read_func", ["read_pickle_glob", "read_pickle_distributed"])
+@pytest.mark.parametrize("to_func", ["to_pickle_glob", "to_pickle_distributed"])
+def test_distributed_pickling(
+    tmp_path, filename, compression, pathlike, read_func, to_func
+):
     data = test_data["int_data"]
     df = pd.DataFrame(data)
 
@@ -264,10 +268,8 @@ def test_distributed_pickling(tmp_path, filename, compression, pathlike):
         if filename_param == "test_default_to_pickle.pkl"
         else contextlib.nullcontext()
     ):
-        df.modin.to_pickle_distributed(
-            str(tmp_path / filename), compression=compression
-        )
-        pickled_df = pd.read_pickle_distributed(
+        getattr(df.modin, to_func)(str(tmp_path / filename), compression=compression)
+        pickled_df = getattr(pd, read_func)(
             str(tmp_path / filename), compression=compression
         )
     df_equals(pickled_df, df)