Browse Source

[sqlalchemy] 'NoneType' object has no attribute 'get'

Note: new tests coming to handle better when connectors are off or not

Fix

Traceback (most recent call last):
  File "/usr/share/hue/desktop/libs/notebook/src/notebook/connectors/sql_alchemy.py", line 99, in decorator
    return func(*args, **kwargs)
  File "/usr/share/hue/desktop/libs/notebook/src/notebook/connectors/sql_alchemy.py", line 230, in execute
    if self.interpreter.get('dialect_properties', {}).get('has_use_statement') and snippet.get('database'):
AttributeError: 'NoneType' object has no attribute 'get'
[10/Dec/2020 06:53:30 -0800] decorators   ERROR    Error running execute
Traceback (most recent call last):
  File "/usr/share/hue/desktop/libs/notebook/src/notebook/decorators.py", line 114, in wrapper
    return f(*args, **kwargs)
  File "/usr/share/hue/desktop/libs/notebook/src/notebook/api.py", line 227, in execute
    response = _execute_notebook(request, notebook, snippet)
  File "/usr/share/hue/desktop/libs/notebook/src/notebook/api.py", line 202, in _execute_notebook
    raise ex
QueryError: 'NoneType' object has no attribute 'get'
Romain Rigaux 5 years ago
parent
commit
32a8b39ef2

+ 10 - 11
desktop/libs/notebook/src/notebook/api_tests.py

@@ -640,38 +640,38 @@ class TestNotebookApiMocked(object):
 def test_get_interpreters_to_show():
   default_interpreters = OrderedDict((
       ('hive', {
-          'name': 'Hive', 'interface': 'hiveserver2', 'type': 'hive', 'is_sql': True, 'options': {}, 'dialect_properties': None,
+          'name': 'Hive', 'interface': 'hiveserver2', 'type': 'hive', 'is_sql': True, 'options': {}, 'dialect_properties': {},
           'is_catalog': False, 'category': 'editor', 'dialect': 'hive'
       }),
       ('spark', {
-          'name': 'Scala', 'interface': 'livy', 'type': 'spark', 'is_sql': False, 'options': {}, 'dialect_properties': None,
+          'name': 'Scala', 'interface': 'livy', 'type': 'spark', 'is_sql': False, 'options': {}, 'dialect_properties': {},
           'is_catalog': False, 'category': 'editor', 'dialect': 'scala'
       }),
       ('pig', {
-          'name': 'Pig', 'interface': 'pig', 'type': 'pig', 'is_sql': False, 'options': {}, 'dialect_properties': None,
+          'name': 'Pig', 'interface': 'pig', 'type': 'pig', 'is_sql': False, 'options': {}, 'dialect_properties': {},
           'is_catalog': False, 'category': 'editor', 'dialect': 'pig'
       }),
       ('java', {
-          'name': 'Java', 'interface': 'oozie', 'type': 'java', 'is_sql': False, 'options': {}, 'dialect_properties': None,
+          'name': 'Java', 'interface': 'oozie', 'type': 'java', 'is_sql': False, 'options': {}, 'dialect_properties': {},
           'is_catalog': False, 'category': 'editor', 'dialect': 'java'
       })
     ))
 
   expected_interpreters = OrderedDict((
       ('java', {
-        'name': 'Java', 'interface': 'oozie', 'type': 'java', 'is_sql': False, 'options': {}, 'dialect_properties': None,
+        'name': 'Java', 'interface': 'oozie', 'type': 'java', 'is_sql': False, 'options': {}, 'dialect_properties': {},
         'is_catalog': False, 'category': 'editor', 'dialect': 'java'
       }),
       ('pig', {
-        'name': 'Pig', 'interface': 'pig', 'is_sql': False, 'type': 'pig', 'options': {}, 'dialect_properties': None,
+        'name': 'Pig', 'interface': 'pig', 'is_sql': False, 'type': 'pig', 'options': {}, 'dialect_properties': {},
         'is_catalog': False, 'category': 'editor', 'dialect': 'pig'
       }),
       ('hive', {
-          'name': 'Hive', 'interface': 'hiveserver2', 'is_sql': True, 'type': 'hive', 'options': {}, 'dialect_properties': None,
+          'name': 'Hive', 'interface': 'hiveserver2', 'is_sql': True, 'type': 'hive', 'options': {}, 'dialect_properties': {},
           'is_catalog': False, 'category': 'editor', 'dialect': 'hive'
       }),
       ('spark', {
-          'name': 'Scala', 'interface': 'livy', 'type': 'spark', 'is_sql': False, 'options': {}, 'dialect_properties': None,
+          'name': 'Scala', 'interface': 'livy', 'type': 'spark', 'is_sql': False, 'options': {}, 'dialect_properties': {},
           'is_catalog': False, 'category': 'editor', 'dialect': 'scala'
       })
     ))
@@ -687,12 +687,11 @@ def test_get_interpreters_to_show():
     appmanager.load_apps(APP_BLACKLIST.get())
     notebook.conf.INTERPRETERS_CACHE = None
 
+    # 'get_interpreters_to_show should return the same as get_interpreters when interpreters_shown_on_wheel is unset'
     assert_equal(
-      list(default_interpreters.values()), get_ordered_interpreters(),
-      'get_interpreters_to_show should return the same as get_interpreters when interpreters_shown_on_wheel is unset'
+      list(default_interpreters.values()), get_ordered_interpreters()
     )
 
-
     resets.append(INTERPRETERS_SHOWN_ON_WHEEL.set_for_testing('java,pig'))
 
     assert_equal(

+ 1 - 1
desktop/libs/notebook/src/notebook/conf.py

@@ -127,7 +127,7 @@ def get_ordered_interpreters(user=None):
       "interface": i['interface'],
       "options": i['options'],
       'dialect': i.get('dialect', i['name']).lower(),
-      'dialect_properties': i.get('dialect_properties'),
+      'dialect_properties': i.get('dialect_properties') or {},  # Empty when connectors off
       'category': i.get('category', 'editor'),
       "is_sql": i.get('is_sql') or \
           i['interface'] in ["hiveserver2", "rdbms", "jdbc", "solr", "sqlalchemy", "ksql", "flink"] or \

+ 2 - 2
desktop/libs/notebook/src/notebook/connectors/sql_alchemy.py

@@ -224,10 +224,10 @@ class SqlAlchemyApi(Api):
     statement = snippet['statement']
 
     if self.options['url'].startswith('phoenix://') or self.options['url'].startswith('presto://') or \
-        self.interpreter.get('dialect_properties') and self.interpreter['dialect_properties']['trim_statement_semicolon']:
+        self.interpreter['dialect_properties'].get('trim_statement_semicolon'):
       statement = statement.strip().rstrip(';')
 
-    if self.interpreter.get('dialect_properties', {}).get('has_use_statement') and snippet.get('database'):
+    if self.interpreter['dialect_properties'].get('has_use_statement') and snippet.get('database'):
       connection.execute('USE ' + snippet['database'])
 
     result = connection.execute(statement)

+ 2 - 1
desktop/libs/notebook/src/notebook/connectors/sql_alchemy_tests.py

@@ -254,7 +254,8 @@ class TestApi(object):
       'options': {
         'url': 'presto://hue:8080/hue',
         'session': {},
-      }
+      },
+      'dialect_properties': {},
     }
 
     with patch('notebook.connectors.sql_alchemy.SqlAlchemyApi._create_engine') as _create_engine: