You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2022/04/08 13:48:03 UTC

[superset] 06/09: fix(dataset): handle missing python_type gracefully (#19553)

This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.5
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 5ca126698a941965f291e0243fa67d65686e4ac5
Author: Ville Brofeldt <33...@users.noreply.github.com>
AuthorDate: Thu Apr 7 14:30:11 2022 +0300

    fix(dataset): handle missing python_type gracefully (#19553)
    
    * fix(dataset): handle missing python_type gracefully
    
    * refactor TEMPORAL_TYPES
    
    (cherry picked from commit d9343a463980cf8b09ed394554fb54200027cc70)
---
 superset/connectors/sqla/utils.py                          | 13 ++++++++++---
 .../migrations/versions/b8d3a24d9131_new_dataset_models.py | 14 +++++++++++---
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/superset/connectors/sqla/utils.py b/superset/connectors/sqla/utils.py
index 14b9071d1d..a2b54201d6 100644
--- a/superset/connectors/sqla/utils.py
+++ b/superset/connectors/sqla/utils.py
@@ -15,6 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 from contextlib import closing
+from datetime import date, datetime, time, timedelta
 from typing import Callable, Dict, List, Optional, Set, TYPE_CHECKING
 
 import sqlparse
@@ -41,7 +42,7 @@ if TYPE_CHECKING:
     from superset.connectors.sqla.models import SqlaTable
 
 
-TEMPORAL_TYPES = {"DATETIME", "DATE", "TIME", "TIMEDELTA"}
+TEMPORAL_TYPES = {date, datetime, time, timedelta}
 
 
 def get_physical_table_metadata(
@@ -172,6 +173,13 @@ def validate_adhoc_subquery(
     return ";\n".join(str(statement) for statement in statements)
 
 
+def is_column_type_temporal(column_type: TypeEngine) -> bool:
+    try:
+        return column_type.python_type in TEMPORAL_TYPES
+    except NotImplementedError:
+        return False
+
+
 def load_or_create_tables(  # pylint: disable=too-many-arguments
     session: Session,
     database_id: int,
@@ -223,8 +231,7 @@ def load_or_create_tables(  # pylint: disable=too-many-arguments
                     name=column["name"],
                     type=str(column["type"]),
                     expression=conditional_quote(column["name"]),
-                    is_temporal=column["type"].python_type.__name__.upper()
-                    in TEMPORAL_TYPES,
+                    is_temporal=is_column_type_temporal(column["type"]),
                     is_aggregation=False,
                     is_physical=True,
                     is_spatial=False,
diff --git a/superset/migrations/versions/b8d3a24d9131_new_dataset_models.py b/superset/migrations/versions/b8d3a24d9131_new_dataset_models.py
index 75f5293034..22aa2f451c 100644
--- a/superset/migrations/versions/b8d3a24d9131_new_dataset_models.py
+++ b/superset/migrations/versions/b8d3a24d9131_new_dataset_models.py
@@ -25,6 +25,7 @@ Create Date: 2021-11-11 16:41:53.266965
 """
 
 import json
+from datetime import date, datetime, time, timedelta
 from typing import Callable, List, Optional, Set
 from uuid import uuid4
 
@@ -35,6 +36,7 @@ from sqlalchemy.engine.url import make_url
 from sqlalchemy.ext.declarative import declarative_base
 from sqlalchemy.orm import backref, relationship, Session
 from sqlalchemy.schema import UniqueConstraint
+from sqlalchemy.sql.type_api import TypeEngine
 from sqlalchemy_utils import UUIDType
 
 from superset import app, db
@@ -230,7 +232,14 @@ class NewDataset(Base):
     external_url = sa.Column(sa.Text, nullable=True)
 
 
-TEMPORAL_TYPES = {"DATETIME", "DATE", "TIME", "TIMEDELTA"}
+TEMPORAL_TYPES = {date, datetime, time, timedelta}
+
+
+def is_column_type_temporal(column_type: TypeEngine) -> bool:
+    try:
+        return column_type.python_type in TEMPORAL_TYPES
+    except NotImplementedError:
+        return False
 
 
 def load_or_create_tables(
@@ -285,8 +294,7 @@ def load_or_create_tables(
                     name=column["name"],
                     type=str(column["type"]),
                     expression=conditional_quote(column["name"]),
-                    is_temporal=column["type"].python_type.__name__.upper()
-                    in TEMPORAL_TYPES,
+                    is_temporal=is_column_type_temporal(column["type"]),
                     is_aggregation=False,
                     is_physical=True,
                     is_spatial=False,