Repository: mathesar-foundation/mathesar

Issue:
IndexError when trying to load Mathesar without any tables
## Description
<!-- A clear and concise description of what the bug is. -->
Mathesar's UI does not load if there are no tables in the UI. There's an error with an index being out of range.

## Expected behavior
<!-- A clear and concise description of what you expected to happen. -->
Mathesar's UI should load.

## To Reproduce
<!-- How can we recreate this bug? Please try to provide a Minimal, Complete, and Verifiable (http://stackoverflow.com/help/mcve) example if code-related. -->
Ensure you have no tables in your connected DB and try to load the Mathesar homepage.

## Additional context
<!-- Add any other context about the problem or screenshots here. -->

Traceback:

```
Environment:


Request Method: GET
Request URL: http://localhost:8000/mathesar_tables

Django Version: 3.1.7
Python Version: 3.9.6
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'django_filters',
 'django_property_filter',
 'mathesar']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/code/mathesar/views/frontend.py", line 42, in index
    "schemas": get_schemas(request),
  File "/code/mathesar/views/frontend.py", line 17, in get_schemas
    return schema_serializer.data
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 745, in data
    ret = super().data
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 246, in data
    self._data = self.to_representation(self.instance)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 663, in to_representation
    return [
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 664, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 515, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 663, in to_representation
    return [
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 664, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 502, in to_representation
    attribute = field.get_attribute(instance)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/fields.py", line 457, in get_attribute
    return get_attribute(instance, self.source_attrs)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/fields.py", line 97, in get_attribute
    instance = getattr(instance, attr)
  File "/usr/local/lib/python3.9/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/code/mathesar/models.py", line 89, in name
    return self._sa_table.name
  File "/usr/local/lib/python3.9/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/code/mathesar/models.py", line 75, in _sa_table
    table = tables.reflect_table_from_oid(
  File "/code/db/tables.py", line 358, in reflect_table_from_oid
    schema, table_name = conn.execute(sel).fetchall()[0]

Exception Type: IndexError at /mathesar_tables
Exception Value: list index out of range
```


Discussion:

Resolving patch:
diff --git a/mathesar/models.py b/mathesar/models.py
--- a/mathesar/models.py
+++ b/mathesar/models.py
@@ -75,12 +75,12 @@ def _sa_table(self):
             table = tables.reflect_table_from_oid(
                 self.oid, self.schema._sa_engine,
             )
-        # We catch this error, since it lets us decouple the cadence of
+        # We catch these errors, since it lets us decouple the cadence of
         # overall DB reflection from the cadence of cache expiration for
         # table names.  Also, it makes it obvious when the DB layer has
         # been altered, as opposed to other reasons for a 404 when
         # requesting a table.
-        except TypeError:
+        except (TypeError, IndexError):
             table = tables.create_empty_table("MISSING")
         return table
 


Test patch: