Redash prend en charge de nombreuses sources de données par défaut. De plus, même si certaines sources de données ne sont pas prises en charge, vous pouvez ajouter de nouvelles sources de données en écrivant query_runner en Python. Vous pouvez écrire simplement query_runner si vous disposez d'une bibliothèque Python pour vous connecter à la source de données cible, mais certaines bases de données peuvent fournir uniquement le pilote JDBC. Étant donné que le pilote JDBC ne peut être appelé qu'à partir du langage JVM, il ne peut pas être intégré directement dans le query_runner de redash. J'ai donc conçu un moyen d'incorporer le pilote JDBC dans Redash, et cet article vous montrera comment le faire.
Cette fois, il s'agit d'une bibliothèque pour appeler le pilote JDBC depuis Python. Utilisez JayDeBeApi. https://github.com/baztian/jaydebeapi
Cette bibliothèque utilise JPype dans l'environnement CPython pour faire le pont entre Python et Java. https://github.com/jpype-project/jpype
Il existe Py4J en tant que bibliothèque pour appeler Java à partir de Python, et il existe un article d'introduction sur Qiita, mais comparé à cela, JPype semble être plus léger car il n'a pas besoin de démarrer un processus Java.
https://www.py4j.org/ https://qiita.com/riverwell/items/e90cbbfdac439e6e9d30
Cette fois, nous intégrerons le pilote JDBC dans redash v5.0.2. Le pilote JDBC à inclure est celui de MySQL, et vous pouvez le télécharger à partir de l'URL suivante. https://dev.mysql.com/downloads/connector/j/5.1.html
Puisque Redash prend en charge MySQL en standard, il n'est pas nécessaire d'incorporer de force le pilote JDBC, mais comme il s'agit d'une base de données largement connue, il est utilisé pour l'explication.
jdbc.py Ensuite, écrivez query_runner. Comment écrire query_runner est bien organisé dans les articles suivants. https://discuss.redash.io/t/creating-a-new-query-runner-data-source-in-redash/347
J'ai créé le query_runner suivant en me référant à l'article ci-dessus.
import json
import logging
import os
import jaydebeapi
from redash.query_runner import *
from redash.settings import parse_boolean
from redash.utils import JSONEncoder
logger = logging.getLogger(__name__)
types_map = {
jaydebeapi.STRING: TYPE_STRING,
jaydebeapi.TEXT: TYPE_STRING,
jaydebeapi.NUMBER: TYPE_INTEGER,
jaydebeapi.FLOAT: TYPE_FLOAT,
jaydebeapi.DECIMAL: TYPE_FLOAT,
jaydebeapi.DATE: TYPE_DATE,
jaydebeapi.DATETIME: TYPE_DATETIME,
jaydebeapi.ROWID: TYPE_STRING,
}
class Jdbc(BaseSQLQueryRunner):
noop_query = "SELECT 1"
@classmethod
def configuration_schema(cls):
schema = {
'type': 'object',
'properties': {
'host': {
'type': 'string',
},
'port': {
'type': 'number',
'default': 3306,
},
'user': {
'type': 'string'
},
'password': {
'type': 'string',
},
'database': {
'type': 'string',
},
},
"order": ['host', 'port', 'user', 'password', 'database'],
'required': ['host', 'port', 'user', 'database'],
'secret': ['password']
}
return schema
@classmethod
def name(cls):
return "jdbc"
@classmethod
def enabled(cls):
try:
import jaydebeapi
except ImportError:
return False
return True
def _get_tables(self, schema):
query = """
SELECT col.table_schema,
col.table_name,
col.column_name
FROM `information_schema`.`columns` col
WHERE col.table_schema NOT IN ('information_schema', 'performance_schema', 'mysql');
"""
results, error = self.run_query(query, None)
if error is not None:
raise Exception("Failed getting schema.")
results = json.loads(results)
for row in results['rows']:
if row['TABLE_SCHEMA'] != self.configuration['database']:
table_name = u'{}.{}'.format(row['TABLE_SCHEMA'], row['TABLE_NAME'])
else:
table_name = row['TABLE_NAME']
if table_name not in schema:
schema[table_name] = {'name': table_name, 'columns': []}
schema[table_name]['columns'].append(row['COLUMN_NAME'])
return schema.values()
def run_query(self, query, user):
import jaydebeapi
connection = None
try:
host = self.configuration.get('host', '')
port = self.configuration.get('port', '')
user = self.configuration.get('user', '')
password = self.configuration.get('password', '')
database = self.configuration.get('database', '')
jclassname = 'com.mysql.jdbc.Driver'
url = 'jdbc:mysql://{}:{}/{}'.format(host, port, database)
driver_args = {'user': user, 'password': password}
jar_path = '/app/redash/query_runner/mysql-connector-java-5.1.47.jar'
connection = jaydebeapi.connect(jclassname, url, driver_args, jar_path)
cursor = connection.cursor()
logger.info("JDBC running query: %s", query)
cursor.execute(query)
data = cursor.fetchall()
if cursor.description is not None:
columns = self.fetch_columns([(i[0], types_map.get(i[1], None)) for i in cursor.description])
rows = [dict(zip((c['name'] for c in columns), row)) for row in data]
data = {'columns': columns, 'rows': rows}
json_data = json.dumps(data, cls=JSONEncoder)
error = None
else:
json_data = None
error = "No data was returned."
cursor.close()
except jaydebeapi.Error as e:
json_data = None
error = str(e.message)
except KeyboardInterrupt:
cursor.close()
error = "Query cancelled by user."
json_data = None
finally:
if connection:
connection.close()
return json_data, error
register(Jdbc)
Je pense que la plupart des traitements, à l'exception de configuration_schema, peuvent être utilisés en commun quel que soit le pilote JDBC utilisé.
Placez le jdbc.py
créé dans la procédure ci-dessus et le fichier jar du pilote JDBC dans redash / query_runner
.
Dockerfile Enfin, créez un conteneur Docker pour exécuter Redash. Étant donné que JRE est requis pour que JPype fonctionne, corrigez le fichier Dockerfile standard redash. Créez également requirements.txt pour installer jaydebeapi.
FROM redash/base:latest
#Ajout de l'installation de JRE
RUN apt-get update && apt-get install -y openjdk-8-jre
COPY redash/requirements.txt redash/requirements_dev.txt redash/requirements_all_ds.txt requirements_jaydebeapi.txt ./
RUN pip install -r requirements.txt -r requirements_dev.txt -r requirements_all_ds.txt -r requirements_jaydebeapi.txt
COPY . ./
RUN npm install && npm run build && rm -rf node_modules
RUN chown -R redash /app
USER redash
ENTRYPOINT ["/app/bin/docker-entrypoint"]
CMD ["server"]
requirements.txt
JayDeBeApi==1.1.1
JPype1==0.6.3
À ce stade, vous pouvez démarrer Redash.
De plus, pour charger le query_runner ajouté dans redash, il est nécessaire d'ajouter redash.query_runner.jdbc
à la variable d'environnement REDASH_ADDITIONAL_QUERY_RUNNERS
et de le démarrer.
Si vous démarrez Redash et regardez l'écran DataSource, vous pouvez voir qu'une source de données appelée JDBC a été ajoutée.
Pour le moment, cela semble un peu décevant car il n'y a pas d'image d'icône montrant la source de données.
Pour mettre une image dans cette partie, placez l'image jdbc.png
dans client / app / assets / images / db-logos
et reconstruisez le conteneur.
Maintenant que nous avons enregistré le pilote JDBC en tant que query_runner, exécutons la requête.
En utilisant JayDeBeApi, j'ai pu utiliser le pilote JDBC avec redash. Avec cela, la variété des sources de données redash s'est étendue et vous pouvez avoir une vie BI merveilleuse.
Recommended Posts