Repository: mathesar-foundation/mathesar

Issue:
If PK of table is a UUID, table wont render
## Description
<!-- A clear and concise description of what the bug is. -->
If PK of table is a UUID, table wont render

## Expected behavior
<!-- A clear and concise description of what you expected to happen. -->
Table should render

## 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. -->
Create a table where PK is a UUID in postgres
## Environment
 - OS: (_eg._ macOS 10.14.6; Fedora 32)
 - Browser: (_eg._ Safari; Firefox)
 - Browser Version: (_eg._ 13; 73)
 - Other info:

## Additional context
<!-- Add any other context about the problem or screenshots here. -->
![image](https://user-images.githubusercontent.com/49372179/222764488-03a78062-e3d7-40f8-99c1-2e992df3c0bf.png)
![image](https://user-images.githubusercontent.com/49372179/222764618-b92138b5-7de4-4ea6-bf6b-cfd362085935.png)



Discussion:
I believe that type is in the other field in the code https://github.com/centerofci/mathesar/blob/develop/mathesar/database/types.py#L145
Thanks for reporting this, @arezitopedia. I've added this to the milestone for our next release.

Note to team: I'm not sure if this is frontend or backend, so I applied both labels. Whoever investigates should update the label once the issue is identified.
I'm observing the following backend error from the columns endpoint.

1. Set up sample data

    ```sql
    CREATE TABLE example_table (
      id UUID DEFAULT uuid_generate_v1mc() PRIMARY KEY,
      column1 TEXT,
      column2 INTEGER,
      column3 BOOLEAN
    );
    INSERT INTO example_table (column1, column2, column3) VALUES
    ('foo', 1, TRUE),
    ('bar', 2, FALSE),
    ('baz', 3, TRUE);
    ```

1. Run reflection

1. Fetch the columns in the table `/api/db/v0/tables/174/columns/`

    Observe the following error

    <details>
    <summary>Traceback</summary>

    ```
    Environment:


    Request Method: GET
    Request URL: http://localhost:8000/api/db/v0/tables/174/columns/?limit=500

    Django Version: 3.1.14
    Python Version: 3.9.16
    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',
    'mathesar.middleware.CursorClosedHandlerMiddleware',
    'mathesar.middleware.PasswordChangeNeededMiddleware',
    'django_userforeignkey.middleware.UserForeignKeyMiddleware',
    'django_request_cache.middleware.RequestCacheMiddleware']



    Traceback (most recent call last):
      File "/code/mathesar/models/base.py", line 714, in __getattribute__
        return super().__getattribute__(name)

    During handling of the above exception ('Column' object has no attribute 'valid_target_types'), another exception occurred:
      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 "/usr/local/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
        return view_func(*args, **kwargs)
      File "/usr/local/lib/python3.9/site-packages/rest_framework/viewsets.py", line 125, in view
        return self.dispatch(request, *args, **kwargs)
      File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
        response = self.handle_exception(exc)
      File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 466, in handle_exception
        response = exception_handler(exc, context)
      File "/code/mathesar/exception_handlers.py", line 59, in mathesar_exception_handler
        raise exc
      File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
        response = handler(request, *args, **kwargs)
      File "/usr/local/lib/python3.9/site-packages/rest_framework/mixins.py", line 43, in list
        return self.get_paginated_response(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 "/code/mathesar/api/serializers/columns.py", line 233, in to_representation
        return super().to_representation(instance)
      File "/code/mathesar/api/serializers/columns.py", line 100, in to_representation
        representation = super().to_representation(instance)
      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/fields.py", line 1882, in to_representation
        return method(value)
      File "/code/mathesar/api/serializers/columns.py", line 240, in get_valid_target_types
        valid_target_types = column.valid_target_types
      File "/code/mathesar/models/base.py", line 720, in __getattribute__
        return getattr(self._sa_column, name)
      File "/code/db/columns/base.py", line 159, in valid_target_types
        and not self.is_default
      File "/code/db/columns/base.py", line 143, in is_default
        and self.type.python_type == default_def[TYPE]().python_type
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/type_api.py", line 416, in python_type
        raise NotImplementedError()

    Exception Type: NotImplementedError at /api/db/v0/tables/174/columns/
    Exception Value: 
    ```

    </details>

There very well could be front end issues here too, but it's a little hard to test with this backend issues present.
I've unassigned myself for now because it seems like the work needed here is backend work, at least for the time being. I can jump back in when we're ready for more front end testing/work.
> I've unassigned myself for now because it seems like the work needed here is backend work, at least for the time being. I can jump back in when we're ready for more front end testing/work.

I've looked into it a bit. I think the only work should be in the backend.
Would like to work on this. Please assign.
> Would like to work on this. Please assign.

@titanventura I've already started work on this, as it's important for our next release. Please consider choosing an issue from the v0.1.2 or Backlog milestones instead:
- https://github.com/centerofci/mathesar/milestone/68
- https://github.com/centerofci/mathesar/milestone/59

Thank you!



Resolving patch:
diff --git a/db/columns/base.py b/db/columns/base.py
--- a/db/columns/base.py
+++ b/db/columns/base.py
@@ -138,6 +138,10 @@ def table_oid(self):
     @property
     def is_default(self):
         default_def = DEFAULT_COLUMNS.get(self.name, False)
+        try:
+            self.type.python_type
+        except NotImplementedError:
+            return False
         return (
             default_def
             and self.type.python_type == default_def[TYPE]().python_type


Test patch:
diff --git a/db/tests/columns/test_base.py b/db/tests/columns/test_base.py
--- a/db/tests/columns/test_base.py
+++ b/db/tests/columns/test_base.py
@@ -4,6 +4,7 @@
 from sqlalchemy import (
     INTEGER, ForeignKey, VARCHAR, CHAR, NUMERIC, ARRAY, JSON
 )
+from sqlalchemy.dialects.postgresql import UUID
 from sqlalchemy.sql.sqltypes import NullType
 
 from db.columns.base import MathesarColumn
@@ -114,6 +115,11 @@ def test_MC_is_default_when_true():
         assert default_col.is_default
 
 
+def test_MC_is_default_with_uuid_col():
+    col = MathesarColumn('id', UUID, primary_key=True, nullable=False)
+    assert not col.is_default
+
+
 def test_MC_is_default_when_false_for_name():
     for default_col in DEFAULT_COLUMNS:
         dc_definition = DEFAULT_COLUMNS[default_col]