Closed bun4uk closed 3 years ago
При SQL с синтаксической ошибкой, мне Tableau выдает HTTP status code: 400 Received error: ...
ошибку от сервера о плохом синтаксисе.
При SQL SELECT * FROM hits_100m_obfuscated
на сервере play-api.clickhouse.tech
, Custom SQL появляется сразу, и данные не извлекаются, если не нажать Update Now/Automatically Update.
Если возможно, опишите пошагово, что и как делать, и что не так, и как хочется, чтоб было, используя DSN, ссылающийся на сервер https://clickhouse.tech/docs/en/getting-started/playground/ например.
@traceon почему-то не получилось из-под Tableau подключиться к playground. Использовали нашу бд.
Записали видео где видно как изменение SQL в custom query приводит к извлечению данных и долгой загрузке. https://www.youtube.com/watch?v=91XXFb8kOgU
На втором видео видно как внесение ошибки в SQL приводит к бесконечной загрузке. https://www.youtube.com/watch?v=k9AUm6IbBfU
Единственную проблему, которую я увидел - это долгий Loading Metadata.
На втором видео вы не подождали пока это не завершится и Tableau не покажет строку с ошибкой от ClickHouse сервера.
Примерно так же будет если написать SELECT 1
, и SEL_x_ECT 1
.
спасибо, почитаю посты p.s. на втором видео я не стал дожидаться ошибки сервера, так как она не приходит. Запрос грузится вечность и приходится закрывать табло-файл
@traceon
пробую подключиться из Tableau к play-api.clickhouse.tech
. При попытке :
An error occurred while communicating with Other Databases (ODBC)
Bad Connection: Tableau could not connect to the data source.
Error Code: B19090E0
SSL Exception: error:14007086:SSL routines:CONNECT_CR_CERT:certificate verify failed
Настройки DSN сейчас такие:
Также пробовал дополнительно указать Proto: https
и SSLMode: allow
. Ошибка не пропала.
Где я мог ошибиться в конфиге?
@bun4uk какая версия драйвера?
@traceon
последняя
1.1.8
С драйвером с мастера:
$ cat ~/.odbc.ini
...
[ClickHouse DSN (dev)]
Driver = ClickHouse ODBC Driver (ANSI)
Description = ClickHouse DSN (dev)
Url = https://playground:clickhouse@play-api.clickhouse.tech:8443/query?database=system
Host = play-api.clickhouse.tech
Port = 8443
Path = /query
Database = system
Username = playground
Password = clickhouse
CALocation = /usr/local/etc/openssl@1.1/cert.pem
Timeout = 3
$ iusql "ClickHouse DSN (dev)"
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> SELECT 1
+----+
| 1 |
+----+
| 1 |
+----+
SQLRowCount returns 1
1 rows fetched
@bun4uk Скорее всего, вам нужно указать CALocation = /usr/local/etc/openssl@1.1/cert.pem
в DSN.
Спасибо! Получилось подключиться.
Я разобрался в каком случае зависает выполнение запроса с ошибкой в синтаксисе. Если установить большой Timeout в DSN конфиге, то процессинг запроса не упадет до тех пор, пока не закончится таймаут.
Steps to reproduce:
Установить Timeout = 1000 в DSN конфигурации
Создать custom SQL в Tableau с следующим запросом и нажать OK:
select * frommm hits_v1
получаем модальное окно, которое будет грузится около 17 минут, и только потом выдаст ошибку.
попытка нажать Cancel
не поможет
Также проверил логи кликхауса. Кликхаус сразу же бросает exception после попытки выполнения неправильного запроса из окна Edit Custom SQL
. В то время, как модальное окно в Tableau продолжает загрузку, пока не закончится Timeout, и только потом выдает ошибку.
Иными словами:
Ну это, собственно, та проблема с "loading metadata". Ссылки на обсуждения, почему это так работает в Табло я привел выше. Не думаю, что что-то можно сделать на уровне драйвера, чтоб обойти это.
Создайте вот такой файл кастомизации ODBC соединения для Tableau по месту ~/.Documents/My Tableau Repository/Datasources/clickhouse.tdc
<?xml version='1.0' encoding='utf-8' ?>
<connection-customization class='genericodbc' enabled='true' version='18.1'>
<vendor name='ClickHouse' />
<driver name='ClickHouse Driver' />
<customizations>
<customization name='CAP_CONNECT_STORED_PROCEDURE' value='no' />
<customization name='CAP_CREATE_TEMP_TABLES' value='no' />
<customization name='CAP_QUERY_GROUP_BY_ALIAS' value='no' />
<customization name='CAP_QUERY_GROUP_BY_DEGREE' value='no' />
<customization name='CAP_QUERY_INOUT_JOINS' value='no' />
<customization name='CAP_QUERY_JOIN_PUSH_DOWN_CONDITION_EXPRESSIONS' value='yes' />
<customization name='CAP_QUERY_JOIN_REQUIRES_SUBQUERY' value='yes' />
<customization name='CAP_QUERY_SORT_BY_DEGREE' value='no' />
<customization name='CAP_QUERY_WHERE_FALSE_METADATA' value='yes' />
<customization name='CAP_SELECT_INTO' value='no' />
<customization name='CAP_SELECT_TOP_INTO' value='no' />
</customizations>
</connection-customization>
и перезапустите Tableau Desktop.
@yurifal Спасибо, тут исправление проблемы с метадатой или еще что-то?
Добавлю, что <driver name='ClickHouse Driver' />
должен точно совпадать с именем драйвера, для которого создан используемый DSN.
@yurifal Спасибо, тут исправление проблемы с метадатой или еще что-то?
по моим представлениям вот эта настройка добавляет в метадата-запросы нужный WHERE:
<customization name='CAP_QUERY_WHERE_FALSE_METADATA' value='yes' />
Три настройки ("стандартные" для ODBC драйверов многих других СУБД) явно запрещают создание времянок и операции с ними:
<customization name='CAP_CREATE_TEMP_TABLES' value='no' />
<customization name='CAP_SELECT_INTO' value='no' />
<customization name='CAP_SELECT_TOP_INTO' value='no' />
Остальные настройки взяты из файла, который уже есть в проекте:
https://github.com/ClickHouse/clickhouse-odbc/blob/master/packaging/clickhouse-odbc.tdc.sample
@yurifal Спасибо! Добавил этот файл, как вы описали. Имя драйвера указал своё. К сожалению, не не увидел изменений. Попытка ввода SQL с синтаксической ошибкой ждет окончания таймаута, перед показом самой ошибки.
1) в логе Табло (в папке Logs файл log.txt) есть ли вот такой текст
found **matching** TDC
? Если есть -- то OK. Если нет -- значит TDC не подтягивается, и тогда нужно пере-проверять имя драйвера.
2) Какой timeout выставлен в odbc.ini ? у меня 3 (секунды). Если взять Ваш пример, то у меня через секунд 5 вываливается вот такая ошибка:
@yurifal в log.txt видно что TDC подтянулся.
{"ts":"2020-10-07T11:07:46.310","pid":91705,"tid":"c3997e","sev":"info","req":"-","sess":"-","site":"-","user":"-","k":"msg","v":"Found matching TDC '/Users/bunchukv/Documents/My Tableau Repository/Datasources/clickhouse.tdc' for class='genericodbc', vendor='ClickHouse', and driver='clickhouse'."}
Таймаут стоит 1000. Меньше не можем поставить, так как есть запрос от аналитиков. Соотсветсвенно ошибка (такая как вы в показали скриншоте) появляется где-то на 1005ой секунде, что ну очень неудобно. Хотя, если посмотреть логи самого кликхауса, то там эта ошибка появляется сразу же после попытки создать Custom SQL.
Если я поставлю таймаут в 3 секунды, то большая часть дашбордов перестанет работать.
Если Custom SQL синтаксически правильный, то Табло возвращает контроль сразу.
Может на этапе создания / правки источников (для работы в Data Pane с Custom SQL) использовать копию DSN но с Timeout = 3 (или сколько будет удобно для отладки кода), а потом в prod сменить DSN и публиковать?
@yurifal Спасибо большое! Такой вариант, в принципе, +- примелим. Немного иначе правда сделали. В настройках DSN оставил Timeout=1000. А в конфиге соединения для Табло руками прописали Timeout=10. Для этапа создания Custom SQL этого достаточно.
Это кстати легко воспроизводится из test\test.py скрипта. Достаточно добавить в connection string у pyodbc.connect ";TIMEOUT=300" и выполнить запрос
query("select * from system.nonexisting")
Скрипт будет висеть 5 минут, в драйвере залипает вызов SQLFreeStmt.
У меня получилось пофиксать эту проблему - https://github.com/ClickHouse/clickhouse-odbc/pull/326 Проверял через pyodbc и на Tableau. Посмотрите плз - нет ли тут еще каких-то подводных камней?
Это кстати легко воспроизводится из test\test.py скрипта. Достаточно добавить в connection string у pyodbc.connect ";TIMEOUT=300" и выполнить запрос
query("select * from system.nonexisting")
Скрипт будет висеть 5 минут, в драйвере залипает вызов SQLFreeStmt.
Может быть попробуете добавить такой тест?
Может быть попробуете добавить такой тест?
В виде питон скрипта легко, а в интеграционных gtest тесты пока не нашел как легко это воспроизвести - в существующем тестовом фреймворке метод closeCursor() никогда не заходит в условие if (connection.session && response && in)
.
Но это легко воспроизводится в связке с ODBC клиентом - например Tableau или pyodbc.
Да, у нас уже есть тесты в питоне - можно добавить туда https://github.com/ClickHouse/clickhouse-odbc/blob/master/test/test.py https://github.com/ClickHouse/clickhouse-odbc/tree/master/test/parameterized
Кстати интересное наблюдение - это не воспроизводится если делать для pyodbc явный вызов connection.close(), но воспроизводится если оставить очистку ресурсов на выходе контекста with (через __exit__
) либо при окончании выполнения скрипта. Что наводит на мысли о не очень корректном обращении с коннекшеном в Tableau.
Да, у нас уже есть тесты в питоне - можно добавить туда https://github.com/ClickHouse/clickhouse-odbc/blob/master/test/test.py https://github.com/ClickHouse/clickhouse-odbc/tree/master/test/parameterized
добавленный тест понятен, подходит?
Да, у нас уже есть тесты в питоне - можно добавить туда https://github.com/ClickHouse/clickhouse-odbc/blob/master/test/test.py https://github.com/ClickHouse/clickhouse-odbc/tree/master/test/parameterized
добавленный тест понятен, подходит?
Да, все выглядит хорошо. Спасибо!
При работе с Custom Query в Tableau есть один очень неудобный момент. Если SQL с синтаксической ошибкой, либо не рабочий – Tableau грузит его без остановки и не выдает ошибку о том, что запрос не компилируется. И приходиться убивать табло файл и начинать все сначала. Если SQL без синтаксических ошибок и написан правильно – Tableau не просто компилирует и собирает метадату, а обрабатывает весь запрос – а это сильно влияет на время выполнения команды. Раньше использовали вертику и там Custom queries создавались моментально. С кликхаусом это становится не очень удобно, к сожалению. Возможно ли как-то настроить драйвер, чтобы создавать custom queries для tableau не дожидаясь прогрузки всего запроса?