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 2019/12/31 12:45:52 UTC
[incubator-superset] branch master updated: Enable running of tests
in tests/db_engine_specs (#8902)
This is an automated email from the ASF dual-hosted git repository.
villebro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push:
new 8fc814f Enable running of tests in tests/db_engine_specs (#8902)
8fc814f is described below
commit 8fc814fc62d8f96f93aaac8223a660e4f9e6d28e
Author: Rob DiCiuccio <ro...@gmail.com>
AuthorDate: Tue Dec 31 12:45:33 2019 +0000
Enable running of tests in tests/db_engine_specs (#8902)
* Enable running of tests in tests/db_engine_specs
* Resolve application context errors
* Refactor and add tests for pyodbc.Row conversion
* Appease isort, regardless of isort:skip
---
superset/db_engine_specs/base.py | 12 ++++++++++
superset/db_engine_specs/exasol.py | 4 +---
superset/db_engine_specs/mssql.py | 5 ++--
.../{athena_tests.py => __init__.py} | 17 -------------
tests/db_engine_specs/athena_tests.py | 2 ++
tests/db_engine_specs/base_engine_spec_tests.py | 28 +++++++++++++++++++++-
tests/db_engine_specs/base_tests.py | 2 ++
tests/db_engine_specs/mssql_tests.py | 15 ++++++++++++
8 files changed, 61 insertions(+), 24 deletions(-)
diff --git a/superset/db_engine_specs/base.py b/superset/db_engine_specs/base.py
index 90dd89b..b267412 100644
--- a/superset/db_engine_specs/base.py
+++ b/superset/db_engine_specs/base.py
@@ -856,3 +856,15 @@ class BaseEngineSpec: # pylint: disable=too-many-public-methods
:return: Compiled column type
"""
return sqla_column_type.compile(dialect=dialect).upper()
+
+ @staticmethod
+ def pyodbc_rows_to_tuples(data: List[Any]) -> List[Tuple]:
+ """
+ Convert pyodbc.Row objects from `fetch_data` to tuples.
+
+ :param data: List of tuples or pyodbc.Row objects
+ :return: List of tuples
+ """
+ if data and type(data[0]).__name__ == "Row":
+ data = [tuple(row) for row in data]
+ return data
diff --git a/superset/db_engine_specs/exasol.py b/superset/db_engine_specs/exasol.py
index 380b598..ea4a400 100644
--- a/superset/db_engine_specs/exasol.py
+++ b/superset/db_engine_specs/exasol.py
@@ -42,6 +42,4 @@ class ExasolEngineSpec(BaseEngineSpec): # pylint: disable=abstract-method
def fetch_data(cls, cursor, limit: int) -> List[Tuple]:
data = super().fetch_data(cursor, limit)
# Lists of `pyodbc.Row` need to be unpacked further
- if data and type(data[0]).__name__ == "Row":
- data = [tuple(row) for row in data]
- return data
+ return cls.pyodbc_rows_to_tuples(data)
diff --git a/superset/db_engine_specs/mssql.py b/superset/db_engine_specs/mssql.py
index c774077..94555b0 100644
--- a/superset/db_engine_specs/mssql.py
+++ b/superset/db_engine_specs/mssql.py
@@ -63,9 +63,8 @@ class MssqlEngineSpec(BaseEngineSpec):
@classmethod
def fetch_data(cls, cursor, limit: int) -> List[Tuple]:
data = super().fetch_data(cursor, limit)
- if data and type(data[0]).__name__ == "Row":
- data = [tuple(row) for row in data]
- return data
+ # Lists of `pyodbc.Row` need to be unpacked further
+ return cls.pyodbc_rows_to_tuples(data)
column_types = [
(String(), re.compile(r"^(?<!N)((VAR){0,1}CHAR|TEXT|STRING)", re.IGNORECASE)),
diff --git a/tests/db_engine_specs/athena_tests.py b/tests/db_engine_specs/__init__.py
similarity index 59%
copy from tests/db_engine_specs/athena_tests.py
copy to tests/db_engine_specs/__init__.py
index 81b790b..13a8339 100644
--- a/tests/db_engine_specs/athena_tests.py
+++ b/tests/db_engine_specs/__init__.py
@@ -14,20 +14,3 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-from superset.db_engine_specs.athena import AthenaEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
-
-
-class AthenaTestCase(DbEngineSpecTestCase):
- def test_convert_dttm(self):
- dttm = self.get_dttm()
-
- self.assertEqual(
- AthenaEngineSpec.convert_dttm("DATE", dttm),
- "from_iso8601_date('2019-01-02')",
- )
-
- self.assertEqual(
- AthenaEngineSpec.convert_dttm("TIMESTAMP", dttm),
- "from_iso8601_timestamp('2019-01-02T03:04:05.678900')",
- )
diff --git a/tests/db_engine_specs/athena_tests.py b/tests/db_engine_specs/athena_tests.py
index 81b790b..b59f500 100644
--- a/tests/db_engine_specs/athena_tests.py
+++ b/tests/db_engine_specs/athena_tests.py
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+from tests.test_app import app # isort:skip
+
from superset.db_engine_specs.athena import AthenaEngineSpec
from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
diff --git a/tests/db_engine_specs/base_engine_spec_tests.py b/tests/db_engine_specs/base_engine_spec_tests.py
index c595792..4ba4e31 100644
--- a/tests/db_engine_specs/base_engine_spec_tests.py
+++ b/tests/db_engine_specs/base_engine_spec_tests.py
@@ -14,15 +14,19 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+from tests.test_app import app # isort:skip
+
+import datetime
from unittest import mock
-from superset import app
from superset.db_engine_specs import engines
from superset.db_engine_specs.base import BaseEngineSpec, builtin_time_grains
from superset.db_engine_specs.sqlite import SqliteEngineSpec
from superset.utils.core import get_example_database
from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from ..fixtures.pyodbcRow import Row
+
class DbEngineSpecsTests(DbEngineSpecTestCase):
def test_extract_limit_from_query(self, engine_spec_class=BaseEngineSpec):
@@ -206,3 +210,25 @@ class DbEngineSpecsTests(DbEngineSpecTestCase):
def test_convert_dttm(self):
dttm = self.get_dttm()
self.assertIsNone(BaseEngineSpec.convert_dttm("", dttm))
+
+ def test_pyodbc_rows_to_tuples(self):
+ # Test for case when pyodbc.Row is returned (odbc driver)
+ data = [
+ Row((1, 1, datetime.datetime(2017, 10, 19, 23, 39, 16, 660000))),
+ Row((2, 2, datetime.datetime(2018, 10, 19, 23, 39, 16, 660000))),
+ ]
+ expected = [
+ (1, 1, datetime.datetime(2017, 10, 19, 23, 39, 16, 660000)),
+ (2, 2, datetime.datetime(2018, 10, 19, 23, 39, 16, 660000)),
+ ]
+ result = BaseEngineSpec.pyodbc_rows_to_tuples(data)
+ self.assertListEqual(result, expected)
+
+ def test_pyodbc_rows_to_tuples_passthrough(self):
+ # Test for case when tuples are returned
+ data = [
+ (1, 1, datetime.datetime(2017, 10, 19, 23, 39, 16, 660000)),
+ (2, 2, datetime.datetime(2018, 10, 19, 23, 39, 16, 660000)),
+ ]
+ result = BaseEngineSpec.pyodbc_rows_to_tuples(data)
+ self.assertListEqual(result, data)
diff --git a/tests/db_engine_specs/base_tests.py b/tests/db_engine_specs/base_tests.py
index d7a57ee..5b08dbf 100644
--- a/tests/db_engine_specs/base_tests.py
+++ b/tests/db_engine_specs/base_tests.py
@@ -20,6 +20,8 @@ from superset.db_engine_specs.mysql import MySQLEngineSpec
from superset.models.core import Database
from tests.base_tests import SupersetTestCase
+from tests.test_app import app # isort:skip
+
class DbEngineSpecTestCase(SupersetTestCase):
def sql_limit_regex(
diff --git a/tests/db_engine_specs/mssql_tests.py b/tests/db_engine_specs/mssql_tests.py
index fabdee1..95cde00 100644
--- a/tests/db_engine_specs/mssql_tests.py
+++ b/tests/db_engine_specs/mssql_tests.py
@@ -14,11 +14,14 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+import unittest.mock as mock
+
from sqlalchemy import column, table
from sqlalchemy.dialects import mssql
from sqlalchemy.sql import select
from sqlalchemy.types import String, UnicodeText
+from superset.db_engine_specs.base import BaseEngineSpec
from superset.db_engine_specs.mssql import MssqlEngineSpec
from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
@@ -87,3 +90,15 @@ class MssqlEngineSpecTest(DbEngineSpecTestCase):
MssqlEngineSpec.convert_dttm("SMALLDATETIME", dttm),
"CONVERT(SMALLDATETIME, '2019-01-02 03:04:05', 20)",
)
+
+ @mock.patch.object(
+ MssqlEngineSpec, "pyodbc_rows_to_tuples", return_value="converted"
+ )
+ def test_fetch_data(self, mock_pyodbc_rows_to_tuples):
+ data = [(1, "foo")]
+ with mock.patch.object(
+ BaseEngineSpec, "fetch_data", return_value=data
+ ) as mock_fetch:
+ result = MssqlEngineSpec.fetch_data(None, 0)
+ mock_pyodbc_rows_to_tuples.assert_called_once_with(data)
+ self.assertEqual(result, "converted")