Repository: googleapis/python-spanner-django

Issue:
django: implement DatabaseIntrospection.get_table_description()
Trying to run `schema.tests` currently fails with:
```
======================================================================
ERROR: test_add_datefield_and_datetimefield_use_effective_default (schema.tests.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/opt/python3.7.0/lib/python3.7/unittest/mock.py", line 1191, in patched
    return func(*args, **keywargs)
  File "/home/tim/code/django/tests/schema/tests.py", line 2711, in test_add_datefield_and_datetimefield_use_effective_default
    columns = self.column_classes(Author)
  File "/home/tim/code/django/tests/schema/tests.py", line 106, in column_classes
    for d in connection.introspection.get_table_description(
AttributeError: 'DatabaseIntrospection' object has no attribute 'get_table_description'
```


Discussion:

Resolving patch:
diff --git a/django_spanner/features.py b/django_spanner/features.py
--- a/django_spanner/features.py
+++ b/django_spanner/features.py
@@ -283,9 +283,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
         # DatabaseIntrospection.get_key_columns() is only required if this
         # backend needs it (which it currently doesn't).
         'introspection.tests.IntrospectionTests.test_get_key_columns',
-        # DatabaseIntrospection.get_table_description() isn't fully implemented:
-        # https://github.com/orijtech/django-spanner/issues/248
-        'introspection.tests.IntrospectionTests.test_get_table_description_col_lengths',
         # DatabaseIntrospection.get_relations() isn't implemented:
         # https://github.com/orijtech/django-spanner/issues/311
         'introspection.tests.IntrospectionTests.test_get_relations',
diff --git a/django_spanner/introspection.py b/django_spanner/introspection.py
--- a/django_spanner/introspection.py
+++ b/django_spanner/introspection.py
@@ -21,6 +21,11 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
         type_pb2.TIMESTAMP: 'DateTimeField',
     }
 
+    def get_field_type(self, data_type, description):
+        if data_type == type_pb2.STRING and description.internal_size == 'MAX':
+            return 'TextField'
+        return super().get_field_type(data_type, description)
+
     def get_table_list(self, cursor):
         """Return a list of table and view names in the current database."""
         # The second TableInfo field is 't' for table or 'v' for view.
@@ -37,13 +42,19 @@ def get_table_description(self, cursor, table_name):
         for line in cursor.description:
             column_name, type_code = line[0], line[1]
             details = column_details[column_name]
+            if details.spanner_type.startswith('STRING'):
+                # Extract the size of the string from, e.g. STRING(#).
+                internal_size = details.spanner_type[7:-1]
+                if internal_size != 'MAX':
+                    internal_size = int(internal_size)
+            else:
+                internal_size = None
             descriptions.append(
                 FieldInfo(
                     column_name,
                     type_code,
-                    # TODO: Fill these in as they're implemented.
                     None,  # display_size
-                    None,  # internal_size
+                    internal_size,
                     None,  # precision
                     None,  # scale
                     details.null_ok,


Test patch: