From 384905e8b648b944862f06d687fa74b0dca75159 Mon Sep 17 00:00:00 2001 From: syerushalmy Date: Thu, 22 Dec 2016 11:32:10 +0200 Subject: [PATCH 1/4] Added get tables query for cassandra and expilicit protocol version to 3 (Also working with cassandra version 2.1 and above) --- query_runner/cass.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/query_runner/cass.py b/query_runner/cass.py index a503f6a9b6..6ec45c78fb 100644 --- a/query_runner/cass.py +++ b/query_runner/cass.py @@ -1,7 +1,7 @@ import json import logging -from redash.query_runner import BaseQueryRunner, register +from redash.query_runner import BaseSQLQueryRunner, register from redash.utils import JSONEncoder logger = logging.getLogger(__name__) @@ -14,7 +14,7 @@ enabled = False -class Cassandra(BaseQueryRunner): +class Cassandra(BaseSQLQueryRunner): noop_query = "SELECT * FROM system.compactions_in_progress" @classmethod @@ -54,12 +54,26 @@ def type(cls): return "Cassandra" def _get_tables(self, schema): - query = """ + CF_query = """ select columnfamily_name from system.schema_columnfamilies where keyspace_name = '{}'; """.format(self.configuration['keyspace']) - results, error = self.run_query(query, None) - return results, error + results, error = self.run_query(CF_query, None) + results = json.loads(results) + for row in results['rows']: + table_name = row['columnfamily_name'] + if table_name not in schema: + schema[table_name] = {'name': table_name, 'columns': []} + CN_query = """ + SELECT column_name FROM system.schema_columns where keyspace_name ='{}' and columnfamily_name ='{}'; + """.format(self.configuration['keyspace'], table_name) + columns, error = self.run_query(CN_query, None) + columns = json.loads(columns) + for col in columns['rows']: + column_name = col['column_name'] + schema[table_name]['columns'].append(col['column_name']) + + return schema.values() def run_query(self, query, user): connection = None @@ -67,9 +81,9 @@ def run_query(self, query, user): if self.configuration.get('username', '') and self.configuration.get('password', ''): auth_provider = PlainTextAuthProvider(username='{}'.format(self.configuration.get('username', '')), password='{}'.format(self.configuration.get('password', ''))) - connection = Cluster([self.configuration.get('host', '')], auth_provider=auth_provider) + connection = Cluster([self.configuration.get('host', '')], auth_provider=auth_provider, protocol_version=3) else: - connection = Cluster([self.configuration.get('host', '')]) + connection = Cluster([self.configuration.get('host', '')], protocol_version=3) session = connection.connect() session.set_keyspace(self.configuration['keyspace']) From 2ec30b7304cecf7395b9541c67900086d6e09f43 Mon Sep 17 00:00:00 2001 From: syerushalmy Date: Fri, 23 Dec 2016 11:32:55 +0200 Subject: [PATCH 2/4] Fixed get_tables for execute 1 query instead of N queries --- query_runner/cass.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/query_runner/cass.py b/query_runner/cass.py index 6ec45c78fb..c6f570fe68 100644 --- a/query_runner/cass.py +++ b/query_runner/cass.py @@ -54,24 +54,18 @@ def type(cls): return "Cassandra" def _get_tables(self, schema): - CF_query = """ - select columnfamily_name from system.schema_columnfamilies where keyspace_name = '{}'; + query = """ + SELECT columnfamily_name, column_name FROM system.schema_columns where keyspace_name ='{}'; """.format(self.configuration['keyspace']) - results, error = self.run_query(CF_query, None) + results, error = self.run_query(query, None) results = json.loads(results) for row in results['rows']: table_name = row['columnfamily_name'] + column_name = row['column_name'] if table_name not in schema: schema[table_name] = {'name': table_name, 'columns': []} - CN_query = """ - SELECT column_name FROM system.schema_columns where keyspace_name ='{}' and columnfamily_name ='{}'; - """.format(self.configuration['keyspace'], table_name) - columns, error = self.run_query(CN_query, None) - columns = json.loads(columns) - for col in columns['rows']: - column_name = col['column_name'] - schema[table_name]['columns'].append(col['column_name']) + schema[table_name]['columns'].append(column_name) return schema.values() From 163d80a853b57e5958d44eba958f027421c13863 Mon Sep 17 00:00:00 2001 From: syerushalmy Date: Sat, 31 Dec 2016 11:11:18 +0200 Subject: [PATCH 3/4] [Cassandra]: Changed test qurey due to error with parsing uuid as a result --- query_runner/cass.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/query_runner/cass.py b/query_runner/cass.py index c6f570fe68..36f6c3e018 100644 --- a/query_runner/cass.py +++ b/query_runner/cass.py @@ -15,7 +15,7 @@ class Cassandra(BaseSQLQueryRunner): - noop_query = "SELECT * FROM system.compactions_in_progress" + noop_query = "SELECT dateof(now()) FROM system.local" @classmethod def enabled(cls): From 8a3bbca61e295741b12522c4d4730170ce2a0187 Mon Sep 17 00:00:00 2001 From: syerushalmy Date: Mon, 2 Jan 2017 14:47:54 +0200 Subject: [PATCH 4/4] Fixed from BaseSQLQueryRunner to BaseQueryRunner and get_schema instead of _get_tables --- query_runner/cass.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/query_runner/cass.py b/query_runner/cass.py index 36f6c3e018..7a577e6e30 100644 --- a/query_runner/cass.py +++ b/query_runner/cass.py @@ -1,7 +1,7 @@ import json import logging -from redash.query_runner import BaseSQLQueryRunner, register +from redash.query_runner import BaseQueryRunner, register from redash.utils import JSONEncoder logger = logging.getLogger(__name__) @@ -14,7 +14,7 @@ enabled = False -class Cassandra(BaseSQLQueryRunner): +class Cassandra(BaseQueryRunner): noop_query = "SELECT dateof(now()) FROM system.local" @classmethod @@ -53,13 +53,15 @@ def configuration_schema(cls): def type(cls): return "Cassandra" - def _get_tables(self, schema): + def get_schema(self, get_stats=False): query = """ SELECT columnfamily_name, column_name FROM system.schema_columns where keyspace_name ='{}'; """.format(self.configuration['keyspace']) results, error = self.run_query(query, None) results = json.loads(results) + + schema = {} for row in results['rows']: table_name = row['columnfamily_name'] column_name = row['column_name']