Repository: modin-project/modin

Issue:
`StorageFormat` config doesn't work with OmniSci IO functions
### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: Ubuntu 20.04
- **Modin version**: 9782a027568d9ad16bf2c3dea434646cec5e4898
- **Python version**: 3.8.12
- **Code we can use to reproduce**:
```
import modin.pandas as pd

import modin.config as cfg
cfg.StorageFormat.put('omnisci')

# df = pd.DataFrame([1]) # works fine
df = pd.read_csv("test") # fails
```

<!--
You can obtain the Modin version with

python -c "import modin; print(modin.__version__)"
-->

### Describe the problem
<!-- Describe the problem clearly here. -->

### Source code / logs
<!-- Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached. Try to provide a reproducible test case that is the bare minimum necessary to generate the problem. -->
```
Traceback (most recent call last):
  File "/modin2/modin/core/execution/dispatching/factories/dispatcher.py", line 129, in _update_factory
    cls.__factory = getattr(factories, factory_name)
AttributeError: module 'modin.core.execution.dispatching.factories.factories' has no attribute 'OmnisciOnRayFactory'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "sample.py", line 46, in <module>
    df = pd.read_csv("test") # fails
  File "/modin2/modin/pandas/io.py", line 135, in read_csv
    return _read(**kwargs)
  File "/modin2/modin/pandas/io.py", line 56, in _read
    from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
  File "/modin2/modin/core/execution/dispatching/factories/dispatcher.py", line 297, in <module>
    Engine.subscribe(FactoryDispatcher._update_factory)
  File "/modin2/modin/config/pubsub.py", line 213, in subscribe
    callback(cls)
  File "/modin2/modin/core/execution/dispatching/factories/dispatcher.py", line 150, in _update_factory
    raise FactoryNotFoundError(
modin.core.execution.dispatching.factories.dispatcher.FactoryNotFoundError: Cannot find a factory for partition 'Omnisci' and execution engine 'Ray'. Potential reason might be incorrect environment variable value for MODIN_STORAGE_FORMAT or MODIN_ENGINE
```


Discussion:
Issue wasn't recognized by CI because, CI tests also set `MODIN_EXPERIMENTAL` and `MODIN_ENGINE` environment variables (which eliminates issue triggering), so to avoid such misses, it is desirable to leave only `MODIN_STORAGE_FORMAT` variable (can be made in the PR with fix for this issue).

Resolving patch:
diff --git a/modin/pandas/io.py b/modin/pandas/io.py
--- a/modin/pandas/io.py
+++ b/modin/pandas/io.py
@@ -53,9 +53,9 @@ def _read(**kwargs):
     -------
     modin.pandas.DataFrame
     """
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     squeeze = kwargs.pop("squeeze", False)
     pd_obj = FactoryDispatcher.read_csv(**kwargs)
     # This happens when `read_csv` returns a TextFileReader object for iterating through
@@ -209,9 +209,9 @@ def read_parquet(
     use_nullable_dtypes: bool = False,
     **kwargs,
 ):
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(
         query_compiler=FactoryDispatcher.read_parquet(
             path=path,
@@ -246,9 +246,9 @@ def read_json(
 ):
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(query_compiler=FactoryDispatcher.read_json(**kwargs))
 
 
@@ -271,9 +271,9 @@ def read_gbq(
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
     kwargs.update(kwargs.pop("kwargs", {}))
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(query_compiler=FactoryDispatcher.read_gbq(**kwargs))
 
 
@@ -297,9 +297,9 @@ def read_html(
 ):
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(query_compiler=FactoryDispatcher.read_html(**kwargs))
 
 
@@ -308,9 +308,9 @@ def read_clipboard(sep=r"\s+", **kwargs):  # pragma: no cover
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
     kwargs.update(kwargs.pop("kwargs", {}))
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(query_compiler=FactoryDispatcher.read_clipboard(**kwargs))
 
 
@@ -345,9 +345,9 @@ def read_excel(
 ):
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     intermediate = FactoryDispatcher.read_excel(**kwargs)
     if isinstance(intermediate, (OrderedDict, dict)):
         parsed = type(intermediate)()
@@ -375,9 +375,9 @@ def read_hdf(
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
     kwargs.update(kwargs.pop("kwargs", {}))
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(query_compiler=FactoryDispatcher.read_hdf(**kwargs))
 
 
@@ -390,9 +390,9 @@ def read_feather(
 ):
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(query_compiler=FactoryDispatcher.read_feather(**kwargs))
 
 
@@ -413,9 +413,9 @@ def read_stata(
 ):
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(query_compiler=FactoryDispatcher.read_stata(**kwargs))
 
 
@@ -430,9 +430,9 @@ def read_sas(
 ):  # pragma: no cover
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(query_compiler=FactoryDispatcher.read_sas(**kwargs))
 
 
@@ -444,9 +444,9 @@ def read_pickle(
 ):
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(query_compiler=FactoryDispatcher.read_pickle(**kwargs))
 
 
@@ -463,9 +463,9 @@ def read_sql(
 ):
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     if kwargs.get("chunksize") is not None:
         ErrorMessage.default_to_pandas("Parameters provided [chunksize]")
         df_gen = pandas.read_sql(**kwargs)
@@ -483,10 +483,10 @@ def read_fwf(
     infer_nrows=100,
     **kwds,
 ):
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
     from pandas.io.parsers.base_parser import parser_defaults
 
-    Engine.subscribe(_update_engine)
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
     kwargs.update(kwargs.pop("kwds", {}))
     target_kwargs = parser_defaults.copy()
@@ -515,9 +515,9 @@ def read_sql_table(
 ):
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(query_compiler=FactoryDispatcher.read_sql_table(**kwargs))
 
 
@@ -534,9 +534,9 @@ def read_sql_query(
 ):
     _, _, _, kwargs = inspect.getargvalues(inspect.currentframe())
 
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(query_compiler=FactoryDispatcher.read_sql_query(**kwargs))
 
 
@@ -546,9 +546,9 @@ def read_spss(
     usecols: Union[Sequence[str], type(None)] = None,
     convert_categoricals: bool = True,
 ):
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     return DataFrame(
         query_compiler=FactoryDispatcher.read_spss(path, usecols, convert_categoricals)
     )
@@ -562,9 +562,9 @@ def to_pickle(
     protocol: int = pickle.HIGHEST_PROTOCOL,
     storage_options: StorageOptions = None,
 ):
+    Engine.subscribe(_update_engine)
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
-    Engine.subscribe(_update_engine)
     if isinstance(obj, DataFrame):
         obj = obj._query_compiler
     return FactoryDispatcher.to_pickle(


Test patch:
diff --git a/modin/experimental/core/execution/native/implementations/omnisci_on_native/test/test_dataframe.py b/modin/experimental/core/execution/native/implementations/omnisci_on_native/test/test_dataframe.py
--- a/modin/experimental/core/execution/native/implementations/omnisci_on_native/test/test_dataframe.py
+++ b/modin/experimental/core/execution/native/implementations/omnisci_on_native/test/test_dataframe.py
@@ -18,13 +18,11 @@
 import pytest
 import re
 
-from modin.config import IsExperimental, Engine, StorageFormat
+from modin.config import StorageFormat
 from modin.pandas.test.utils import io_ops_bad_exc, default_to_pandas_ignore_string
 from .utils import eval_io, ForceOmnisciImport, set_execution_mode, run_and_compare
 from pandas.core.dtypes.common import is_list_like
 
-IsExperimental.put(True)
-Engine.put("native")
 StorageFormat.put("omnisci")
 
 import modin.pandas as pd