Repository: modin-project/modin

Issue:
Modin read_parquet api throws 'NoneType' object is not subscriptable
### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**:Ubuntu 18.04
- **Modin version** (`modin.__version__`): latest
- **Python version**: 3.6.9
- **Code we can use to reproduce**:

```python
import ray
import modin.pandas as pd

if __name__ == '__main__':
    path= "path/to/parquet/part-0001-2020-05-16-064533-0990-r0101.snappy.parquet"
    modin_df = pd.read_parquet(path)
    modin_df.to_parquet("path/to/parquet/test.parquet")
    print(f'Modin DF len = {len(modin_df)}')
```

### Describe the problem
I have generated the parquet data through spark and I'm trying to read single file partition from parquet folder and it throws "NoneType' object is not subscriptable" 

### Source code / logs

Log trace:
```
Traceback (most recent call last):
  File "modinTest.py", line 6, in <module>
    modin_df = pd.read_parquet(path)
  File "/home/srds/virtual_env/airflow_venv/lib/python3.6/site-packages/modin/pandas/io.py", line 42, in read_parquet
    path=path, columns=columns, engine=engine, **kwargs
  File "/home/srds/virtual_env/airflow_venv/lib/python3.6/site-packages/modin/data_management/factories.py", line 57, in read_parquet
    return cls._determine_engine()._read_parquet(**kwargs)
  File "/home/srds/virtual_env/airflow_venv/lib/python3.6/site-packages/modin/data_management/factories.py", line 61, in _read_parquet
    return cls.io_cls.read_parquet(**kwargs)
  File "/home/srds/virtual_env/airflow_venv/lib/python3.6/site-packages/modin/engines/base/io/column_stores/parquet_reader.py", line 79, in read
    meta.metadata[b"pandas"].replace(b"null", b"None")
TypeError: 'NoneType' object is not subscriptable
```


Discussion:
I have the same problem. Is there a workaround?
This should be fixable, adding to next release.
Just ran into the same issue, but in my case it tells me `NameError: name 'false' is not defined`:

<details>

```python
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-32-4cf9fb47ce92> in <module>
----> 1 deletions_df = pd.read_parquet(snakemake.input["deletions_pq"], engine="pyarrow")
      2 deletions_df

/opt/modules/anaconda/lib/python3.7/site-packages/modin/pandas/io.py in read_parquet(path, engine, columns, **kwargs)
    152     return DataFrame(
    153         query_compiler=EngineDispatcher.read_parquet(
--> 154             path=path, columns=columns, engine=engine, **kwargs
    155         )
    156     )

/opt/modules/anaconda/lib/python3.7/site-packages/modin/data_management/factories/dispatcher.py in read_parquet(cls, **kwargs)
     98     @classmethod
     99     def read_parquet(cls, **kwargs):
--> 100         return cls.__engine._read_parquet(**kwargs)
    101 
    102     @classmethod

/opt/modules/anaconda/lib/python3.7/site-packages/modin/data_management/factories/factories.py in _read_parquet(cls, **kwargs)
     81     @classmethod
     82     def _read_parquet(cls, **kwargs):
---> 83         return cls.io_cls.read_parquet(**kwargs)
     84 
     85     @classmethod

/opt/modules/anaconda/lib/python3.7/site-packages/modin/engines/base/io/file_dispatcher.py in read(cls, *args, **kwargs)
     27     @classmethod
     28     def read(cls, *args, **kwargs):
---> 29         query_compiler = cls._read(*args, **kwargs)
     30         # TODO (devin-petersohn): Make this section more general for non-pandas kernel
     31         # implementations.

/opt/modules/anaconda/lib/python3.7/site-packages/modin/engines/base/io/column_stores/parquet_dispatcher.py in _read(cls, path, engine, columns, **kwargs)
    117                 # computation.
    118                 index_columns = eval(
--> 119                     meta.metadata[b"pandas"].replace(b"null", b"None")
    120                 ).get("index_columns", [])
    121                 column_names = [c for c in column_names if c not in index_columns]

/opt/modules/anaconda/lib/python3.7/site-packages/modin/engines/base/io/column_stores/parquet_dispatcher.py in <module>

NameError: name 'false' is not defined
```

</details>

My modin version is 0.8.3 from conda.
Thanks @Hoeze that's very helpful!
Got the same error as Hoeze with python 3.8 and modin==0.8.3

Resolving patch:
diff --git a/modin/engines/base/io/column_stores/parquet_dispatcher.py b/modin/engines/base/io/column_stores/parquet_dispatcher.py
--- a/modin/engines/base/io/column_stores/parquet_dispatcher.py
+++ b/modin/engines/base/io/column_stores/parquet_dispatcher.py
@@ -107,17 +107,22 @@ def _read(cls, path, engine, columns, **kwargs):
             else:
                 meta = ParquetFile(path).metadata
                 column_names = meta.schema.names
-            if meta is not None:
-                # This is how we convert the metadata from pyarrow to a python
-                # dictionary, from which we then get the index columns.
-                # We use these to filter out from the columns in the metadata since
-                # the pyarrow storage has no concept of row labels/index.
-                # This ensures that our metadata lines up with the partitions without
-                # extra communication steps once we `have done all the remote
-                # computation.
-                index_columns = eval(
-                    meta.metadata[b"pandas"].replace(b"null", b"None")
-                ).get("index_columns", [])
-                column_names = [c for c in column_names if c not in index_columns]
+
+            if meta is not None and meta.metadata is not None:
+                pandas_metadata = meta.metadata.get(b"pandas", None)
+                if pandas_metadata is not None:
+                    import json
+
+                    # This is how we convert the metadata from pyarrow to a python
+                    # dictionary, from which we then get the index columns.
+                    # We use these to filter out from the columns in the metadata since
+                    # the pyarrow storage has no concept of row labels/index.
+                    # This ensures that our metadata lines up with the partitions without
+                    # extra communication steps once we have done all the remote
+                    # computation.
+                    index_columns = json.loads(pandas_metadata.decode("utf8")).get(
+                        "index_columns", []
+                    )
+                    column_names = [c for c in column_names if c not in index_columns]
             columns = [name for name in column_names if not PQ_INDEX_REGEX.match(name)]
         return cls.build_query_compiler(path, columns, **kwargs)


Test patch:
diff --git a/modin/pandas/test/test_io.py b/modin/pandas/test/test_io.py
--- a/modin/pandas/test/test_io.py
+++ b/modin/pandas/test/test_io.py
@@ -1174,6 +1174,28 @@ def test_read_parquet_s3(self):
         modin_df_s3 = pd.read_parquet(dataset_url)
         df_equals(pandas_df, modin_df_s3)
 
+    def test_read_parquet_without_metadata(self):
+        """Test that Modin can read parquet files not written by pandas."""
+        from pyarrow import csv
+        from pyarrow import parquet
+
+        parquet_fname = get_unique_filename(extension="parquet")
+        csv_fname = get_unique_filename(extension="parquet")
+        pandas_df = pandas.DataFrame(
+            {
+                "idx": np.random.randint(0, 100_000, size=2000),
+                "A": np.random.randint(0, 10, size=2000),
+                "B": ["a", "b"] * 1000,
+                "C": ["c"] * 2000,
+            }
+        )
+        pandas_df.to_csv(csv_fname, index=False)
+        # read into pyarrow table and write it to a parquet file
+        t = csv.read_csv(csv_fname)
+        parquet.write_table(t, parquet_fname)
+
+        df_equals(pd.read_parquet(parquet_fname), pandas.read_parquet(parquet_fname))
+
     def test_to_parquet(self):
         modin_df, pandas_df = create_test_dfs(TEST_DATA)
         eval_to_file(