サマリー
- Superset から TD に接続する方法として pyhive、trino-python-client、sqlalchemy-trino を試したがどれも現時点までの実装だと対応が難しそう。
- pyhive にパッチを当てることで接続でき、クエリが実行できることを確認した。
- [2022-02-08 追記] 最新の trino-python-client をインストールすることでクエリが実行できることを確認した。
Superset を localhost で動かす
こんな感じの Dockerfile を用意して、
FROM apache/superset:1.4.0 USER root RUN superset db upgrade && \ superset init && \ superset fab create-admin \ --username superset-admin \ --password superset-admin \ --firstname Superset \ --lastname Admin \ --email admin@superset.com
build して run する。
docker build . -t superset-td-example docker run -d -p 8088:8088 superset-td-example
http://localhost:8088/ にアクセスして、Dockerfile で指定したユーザー名とパスワードを入力し、ログインできることを確認。
TD への接続確認
PyHive で動作確認
PyHive は Python から Hive/Presto に接続する際に使われる一番ポピュラーなライブラリであり、sqlalchemy の Hive/Presto dialect である。 上記の Superset の用意した docker image にもすで含まれており、デフォルトでは Hive/Presto への接続ではこれが使われる。
Superset のコンソール上から database を作成し、接続テストする。 設定はこんな感じ。<<TD_API_KEY>> は実際の API key に置換する。
# SQLALCHEMY URI presto://api-presto.treasuredata.com/td-presto/sample_datasets
# ADVANCED > Others > ENGINE PARAMETERS { "connect_args": { "username": "<<TD_API_KEY>>", "port": 443, "protocol": "https" } }
Test Connection を実行すると、Connection looks good!
と表示され成功するが、 Connect を実行すると An error occurred while creating databases: Fatal error
と表示され失敗する。docker のエラーログを確認すると Missing X-Presto-User header
が原因であることが分かる。
sqlalchemy.exc.OperationalError: (pyhive.exc.OperationalError) Unexpected status code 401 b'{"id":"20220206_075652_49433_c4j75","infoUri":"http://not_accessible","stats":{"state":"FAILED","queued":false,"scheduled":false,"nodes":0,"totalSplits":0,"queuedSplits":0,"runningSplits":0,"completedSplits":0,"cpuTimeMillis":0,"wallTimeMillis":0,"queuedTimeMillis":0,"elapsedTimeMillis":0,"processedRows":0,"processedBytes":0,"peakMemoryBytes":0,"spilledBytes":0},"error":{"message":"Missing X-Presto-User header","sqlState":"FAILED","errorCode":4,"errorName":"PERMISSION_DENIED","errorType":"USER_ERROR","errorLocation":{"lineNumber":1,"columnNumber":1},"failureInfo":{"type":"com.treasuredata.prestobase.core.PrestobaseException","message":"[InvalidArgument] Missing X-Presto-User header","suppressed":[],
同様の Issue は PyHive に報告されており、当該 PR は close はされているが問題は解消していないようだ。
更に、今年 2022年 に入り、PyHive は unsupported であるというという明記がされてしまったため修正が取り入れられることはなさそうだ。
Mention that project is unsupported
Update README.rst by bkyryliuk · Pull Request #423 · dropbox/PyHive · GitHub
PyHive では trino の dialect もサポートしていたようだがベースは presto のものであり問題は解消されない。
trino-python-client で動作確認
trino-python-client では trino の sqlalchemy の dialect をサポートしている。 と言うことで、上記の Dockerfile に
pip uninstall -y pyhive && \ pip install trino
を追加して build & run する。 再度、Superset のコンソール上から database を作成し、接続テストする。
# SQLALCHEMY URI trino://api-presto.treasuredata.com/td-presto/sample_datasets
# ADVANCED > Others > ENGINE PARAMETERS { "connect_args": { "user": "<<TD_API_KEY>>", "port": 443, "http_scheme": "https" } }
Test Connection を実行すると ERROR: line 1:8: Function 'version' not registered
が表示され失敗する。
元の実装であった sqlalchemy-trino の issue を確認すると、どうやら当該 trino の dialect でサポートしている trino のバージョンは 352 以降らしい。エラーの元となっている select version();
がどこかの時点でライブラリで使用されるようになり、それをサポートしている trino が 352 以降ということのようだ。
TD のサポートする trino のバージョンは 350 が最新であり、アップグレードによる問題の解消はできない。
[2022-02-08 追記]
と twitter でつぶやいたところ、ebyhr さんに補足され、trino-python-client の修正パッチを書いていただいた!
このパッチでもSupersetとしては問題なさそうでしょうか?https://t.co/30ylmCd9Vf
— Yuya Ebihara (@ebyhr) 2022年2月7日
server_version_info: Optional[Tuple[Any, ...]] """a tuple containing a version number for the DB backend in use. This value is only available for supporting dialects, and is typically populated during the initial connection to the database. """
[https://github.com/sqlalchemy/sqlalchemy/blob/main/lib/sqlalchemy/engine/interfaces.py#L518-L522:title]
どうやら server_version_info は dialect の実装補助のための情報で、trino-python-client では使っていなく、必須ではないようだ。 ということで、
pip uninstall -y pyhive && \ pip install trino==0.310.0
みたいな感じで最新のものを使うとクエリを実行できることを確認した。Happy!
[追記ここまで]
sqlalchemy-trino で動作確認
それではと、上記の select version();
の導入前の sqlalchemy-trino を使うことで問題が解消されるか確認する。
Dockerfile の pip 実行部を trino から sqlalchemy-trino に修正して、改めて build & run する。
pip uninstall -y pyhive && \ pip install git+https://github.com/dungdm93/sqlalchemy-trino.git@d343c46b79475b577c8a1fa166dfec30112c10e3
再度 Database を作成し、Test Connection を実行すると ERROR: Access Denied: Cannot select from table runtime.nodes
が表示され失敗する。
これは、TD が runtime.nodesというシステム用テーブルへのアクセスを許可していないことに起因するため、こちらも解消は厳しそうだ。
誰も心当たりのないPrestoクエリについて - PLAZMA by Treasure Data
PyHive にパッチを当てて動作確認
pyhive、trino-python-client、sqlalchemy-trino の現時点までの実装だと対応が難しそうなので、パッチを当てることで接続できるか確認する。 pyhive を fork して下記 Toru-san の PR の修正をそのまま pyhive に適用し、適当に push する。
Dockerfile の pip 実行部を下記のように修正して、再度 build & run。
pip uninstall -y pyhive && \ pip install git+https://github.com/satoshihirose/pyhive.git@develop
Superset にログインし、上記 pyhive のセクションの設定のまま Database を作成すると、成功した。
クエリエディターから実際にクエリを実行できることを確認した。