Redash unterstützt standardmäßig viele Datenquellen. Selbst wenn einige Datenquellen nicht unterstützt werden, können Sie neue Datenquellen hinzufügen, indem Sie query_runner in Python schreiben. Sie können query_runner direkt schreiben, wenn Sie über eine Python-Bibliothek verfügen, um eine Verbindung zur Zieldatenquelle herzustellen. Einige DBs stellen jedoch möglicherweise nur den JDBC-Treiber bereit. Da der JDBC-Treiber nur aus der JVM-Sprache aufgerufen werden kann, kann er nicht direkt in den query_runner von redash integriert werden. Daher habe ich eine Möglichkeit entwickelt, den JDBC-Treiber in redash zu integrieren. Dieser Artikel zeigt Ihnen, wie das geht.
Diesmal ist es eine Bibliothek zum Aufrufen des JDBC-Treibers von Python. Verwenden Sie JayDeBeApi. https://github.com/baztian/jaydebeapi
Diese Bibliothek verwendet JPype in der CPython-Umgebung, um eine Brücke zwischen Python und Java zu schlagen. https://github.com/jpype-project/jpype
Es gibt Py4J als Bibliothek zum Aufrufen von Java aus Python und einen einführenden Artikel zu Qiita. Im Vergleich dazu scheint JPype jedoch leichter zu sein, da kein Java-Prozess gestartet werden muss.
https://www.py4j.org/ https://qiita.com/riverwell/items/e90cbbfdac439e6e9d30
Dieses Mal werden wir den JDBC-Treiber in redash v5.0.2 einbetten. Der einzuschließende JDBC-Treiber ist der von MySQL und kann von der folgenden URL heruntergeladen werden. https://dev.mysql.com/downloads/connector/j/5.1.html
Da Redash MySQL standardmäßig unterstützt, muss der JDBC-Treiber nicht zwangsweise eingebunden werden. Da es sich jedoch um eine weithin bekannte Datenbank handelt, wird sie zur Erläuterung verwendet.
jdbc.py Als nächstes schreiben Sie query_runner. Wie man query_runner schreibt, ist in den folgenden Artikeln gut organisiert. https://discuss.redash.io/t/creating-a-new-query-runner-data-source-in-redash/347
Ich habe den folgenden query_runner unter Bezugnahme auf den obigen Artikel erstellt.
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)
Ich denke, dass der größte Teil der Verarbeitung mit Ausnahme von configuration_schema gemeinsam verwendet werden kann, unabhängig davon, welcher JDBC-Treiber verwendet wird.
Platzieren Sie die in der obigen Prozedur erstellte jdbc.py
und die JDBC-Treiber-JAR-Datei in redash / query_runner
.
Dockerfile Erstellen Sie schließlich einen Docker-Container, um Redash auszuführen. Da für JPype JRE erforderlich ist, patchen Sie die Redash-Standard-Docker-Datei. Erstellen Sie außerdem die Datei require.txt, um jaydebeapi zu installieren.
FROM redash/base:latest
#JRE-Installation hinzugefügt
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
An diesem Punkt können Sie mit dem Redash beginnen. Um den hinzugefügten query_runner in redash zu laden, muss außerdem "redash.query_runner.jdbc" zur Umgebungsvariablen "REDASH_ADDITIONAL_QUERY_RUNNERS" hinzugefügt und gestartet werden.
Wenn Sie mit dem Redash beginnen und den DataSource-Bildschirm anzeigen, sehen Sie, dass eine Datenquelle namens JDBC hinzugefügt wurde.
Im Moment sieht es etwas enttäuschend aus, da es kein Symbolbild gibt, das die Datenquelle zeigt. Um ein Bild in diesen Teil einzufügen, platzieren Sie das Bild "jdbc.png " in "client / app / assets / images / db-logos" und erstellen Sie den Container erneut.
Nachdem wir den JDBC-Treiber als query_runner registriert haben, führen wir die Abfrage aus.
Mit JayDeBeApi konnte ich den JDBC-Treiber mit Redash verwenden. Damit hat sich die Vielfalt der Redash-Datenquellen erweitert, und Sie können ein wundervolles BI-Leben führen.
Recommended Posts