Coder Social home page Coder Social logo

flexberry / newplatform.flexberry.orm.clickhousedataservice Goto Github PK

View Code? Open in Web Editor NEW
1.0 17.0 1.0 178 KB

[WIP] Yandex ClickHouse support by Flexberry ORM

Home Page: https://www.nuget.org/packages/NewPlatform.Flexberry.ORM.ClickHouseDataService

License: MIT License

C# 100.00% Batchfile 0.01%
bigdata clickhouse

newplatform.flexberry.orm.clickhousedataservice's Introduction

Flexberry ORM ClickHouseDataService

CI

Yandex ClickHouse support by Flexberry ORM.

Запуск тестов

Перед запуском тестов нужно запустить Docker-контейнер с ClickHouse:

docker-compose up -d

newplatform.flexberry.orm.clickhousedataservice's People

Contributors

antibus3 avatar antoniv8 avatar antoniv87 avatar pashamasalkin avatar s-andrey avatar turcons avatar vlanin avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

antibus3

newplatform.flexberry.orm.clickhousedataservice's Issues

ClickHouse бъёт данные на блоки и через ClickHouseDataService они приходят не все

Описание ошибки

Вычитываются не все данные, которые имеются в БД ClickHouse и удовлетворяют условиям фильтрации

Ожидаемое поведение

Должны возвращаться все данные, которые удовлетворяют условиям фильтрации

Пути решения

В ReadMe к ClickHouse.ADO написано, что надо использовать NextResult. У нас в методе ReadFirst этот метод вызывается.
Дальнейшая вычитка производится в методе ReadNext, который не переопределён в ClickHouseDataService – используется реализация из SQLDataService.
Соответственно, в этом методе ReadNext происходит вычитка данных в цикле, пока что-то приходит из reader.Read().
Я предполагаю, что может быть после окончания reader.Read() надо попробовать снова выполнить NextResult(). Для этого нужно в ClickHouseDataService переопределить метод ReadNext, скопировать его код из ORM и добавить недостающую логику с NextResult.

Исходный код

  • Нужно залогиниться в GitHub (зарегистрироваться, если нет учётной записи)
  • Сделать Fork репозитория: https://github.com/Flexberry/NewPlatform.Flexberry.ORM.ClickHouseDataService кнопка справа
  • Перейти в свой fork и сделать его git clone.
  • После этого ты можешь собрать приложение в Visual Studio (мы пользуемся версией 2019, но и более старые, наверное, тоже можно).
  • Доработки можешь смело коммитить и пушить в свой форкнутый репозиторий.
  • Если что-то непонятно, то тут есть подробности о том, как работать с гитом и не только: https://flexberry.github.io/ru/tds_module2-learn.html
  • Собранную локально сборку можно подкладывать прямо в \packages\NewPlatform.Flexberry.ORM.ClickHouseDataService.1.0.0-alpha02\lib\net45\
  • После этого надо пересобрать прикладное решение, студия подтянет при сборке новую dll и pdb из папки packages в папку bin
  • Можно подключаться под отладкой к коду ClickHouseDataService через меню Debug – Attach to process. Если это веб-сайт, то надо подлючаться к процессу iisexpress. Важно, чтобы pdb-файл соответствовал dll.
  • После выполнения исправлений в веб-интерфейсе GitHub-а надо сделать Pull Request в нашу ветку. После проверки и принятия будет собран новый NuGet-пакет.

Примерная оценка трудоёмкости

8ч.

Реализовать ClickHouseDataService в полном объёме

Цель

Реализовать ClickHouseDataService в полном объёме.

Функциональные требования

  1. Реализовать интерфейс IDataService для поддержки работы приложений с хранилищем ClickHouse
  2. Встроенный язык запросов должен быть реализован в объёме, не меньше чем для PostgreSQL (при наличии поддержки выражения со стороны ClickHouse)
  3. Проверить на выполнимость интеграционных тестов ORM с хранилищем ClickHouse, при необходимости доработать ClickHouseDataService
  4. Проверить на совместимость с ODataService, реализовать поддержку ClickHouse для имеющихся интеграционных тестов ODataService, при необходимости доработать ClickHouseDataService

Требования к реализации

  • В качестве примера реализации можно использовать PostgresDataService и MongoDbDataService (не полная поддержка).
  • Для создания структуры хранения использовать плагин генерации ORM в Flexberry Designer.

Исходный код

В данном репозитории.

Проект на GitHub: <адрес>
Ветка: develop

Документация

  • Ссылка - дополнить документацию про ORM

Тесты

  • Требуется разработать тесты

Аналоги, примеры реализации

В качестве примера реализации можно использовать PostgresDataService и MongoDbDataService.

Примерная оценка трудоёмкости

*<Сколько времени в часах может понадобиться на решение поставленной задачи среднему по знаниям и навыкам разработчику. В эту оценку времени в т.ч. входит работа над тестами и документацией. Задачи не должны быть сформулированы на длительности более 16 ч.

Полезные ссылки, скриншоты

<Дополнительный материал который может пригодиться, чтобы успешно справиться с поставленной задачей (номер задачи, запись на форуме и т.д.)>

Генерируются лишние скобки в секции FROM в сложном SQL-запросе

Описание ошибки

В секции FROM добавляются скобки, которые не работают с ClickHouse.

Ожидаемое поведение

В секции FROM в SQL запросе не должно быть обрамляющих скобок

Шаги воспроизведения

Генератор сгенерил такой вот запрос:

SELECT 
"Источник",
"Источник.Editor",
"Время",
"НомерТС",
"Скорость",
"ОграничениеСкорости",
"ИдентификаторМатериала",
"STORMMainObjectKey",
"STORMJoinedMasterKey0",
"STORMJoinedMasterKey1",
"STORMNETDATAOBJECTTYPE"
FROM (
SELECT 
"ФотофиксацияТС0"."Источник" as "Источник",
"ФотофиксацияТСИсточник0"."Editor" as "Источник.Editor",
"ФотофиксацияТС0"."Время" as "Время",
"ФотофиксацияТС0"."НомерТС" as "НомерТС",
"ФотофиксацияТС0"."Скорость" as "Скорость",
"ФотофиксацияТС0"."ОграничениеСкорости" as "ОграничениеСкорости",
"ФотофиксацияТС0"."ИдентификаторМатериала" as "ИдентификаторМатериала",
"ФотофиксацияТС0"."primaryKey" as "STORMMainObjectKey",
"ФотофиксацияТСИсточник0"."primaryKey" as "STORMJoinedMasterKey0",
"ФотофиксацияТС0"."Источник" as "STORMJoinedMasterKey1", 0 as "STORMNETDATAOBJECTTYPE"
FROM 
("ФотофиксацияТС" "ФотофиксацияТС0" 
                 LEFT JOIN  "Источник" "ФотофиксацияТСИсточник0"
                ON "ФотофиксацияТС0"."Источник" = "ФотофиксацияТСИсточник0"."primaryKey")
) "STORMGENERATEDQUERY"
WHERE ( "STORMMainObjectKey" = 'a46002e9-4913-44ca-9857-2587af9ccfbf')

И тестовое приложение упало.

Попробовал при помощи clickhouse-client его выполнить, выдает:

Syntax error: failed at position 1200:

SELECT  "Источник", "Источник.Editor", "Время", "НомерТС", "Скорость", "ОграничениеСкорости", "ИдентификаторМатериала", "STORMMainObjectKey", "STORMJoinedMasterKey0", "STORMJoinedMasterKey1", "STORMNETDATAOBJECTTYPE" FROM ( SELECT  "ФотофиксацияТС0"."Источник" as "Источник", "ФотофиксацияТСИсточник0"."Editor" as "Источник.Editor", "ФотофиксацияТС0"."Время" as "Время", "ФотофиксацияТС0"."НомерТС" as "НомерТС", "ФотофиксацияТС0"."Скорость" as "Скорость", "ФотофиксацияТС0"."ОграничениеСкорости" as "ОграничениеСкорости", "ФотофиксацияТС0"."ИдентификаторМатериала" as "ИдентификаторМатериала", "ФотофиксацияТС0"."primaryKey" as "STORMMainObjectKey", "ФотофиксацияТСИсточник0"."primaryKey" as "STORMJoinedMasterKey0", "ФотофиксацияТС0"."Источник" as "STORMJoinedMasterKey1", 0 as "STORMNETDATAOBJECTTYPE" FROM  ("ФотофиксацияТС" "ФотофиксацияТС0"   LEFT JOIN  "Источник" "ФотофиксацияТСИсточник0"  ON "ФотофиксацияТС0"."Источник" = "ФотофиксацияТСИсточник0"."primaryKey") ) "STORMGENERATEDQUERY" WHERE ( "STORMMainObjectKey" = 'a46002e9-4913-44ca-9857-2587af9ccfbf');

Expected one of: SELECT query, possibly with UNION, SELECT query, subquery, possibly with UNION, SELECT, WITH, SELECT subquery, list of elements, SELECT query

Исправил запрос на:

SELECT  "Источник", "Источник.Editor", "Время", "НомерТС", "Скорость", "ОграничениеСкорости", "ИдентификаторМатериала", "STORMMainObjectKey", "STORMJoinedMasterKey0", "STORMJoinedMasterKey1", "STORMNETDATAOBJECTTYPE" FROM ( SELECT  "ФотофиксацияТС0"."Источник" as "Источник", "ФотофиксацияТСИсточник0"."Editor" as "Источник.Editor", "ФотофиксацияТС0"."Время" as "Время", "ФотофиксацияТС0"."НомерТС" as "НомерТС", "ФотофиксацияТС0"."Скорость" as "Скорость", "ФотофиксацияТС0"."ОграничениеСкорости" as "ОграничениеСкорости", "ФотофиксацияТС0"."ИдентификаторМатериала" as "ИдентификаторМатериала", "ФотофиксацияТС0"."primaryKey" as "STORMMainObjectKey", "ФотофиксацияТСИсточник0"."primaryKey" as "STORMJoinedMasterKey0", "ФотофиксацияТС0"."Источник" as "STORMJoinedMasterKey1", 0 as "STORMNETDATAOBJECTTYPE" FROM "ФотофиксацияТС" "ФотофиксацияТС0"   LEFT JOIN  "Источник" "ФотофиксацияТСИсточник0"  ON "ФотофиксацияТС0"."Источник" = "ФотофиксацияТСИсточник0"."primaryKey") "STORMGENERATEDQUERY" WHERE ( "STORMMainObjectKey" = 'a46002e9-4913-44ca-9857-2587af9ccfbf');

/* убрал скобки в FROM ( "ФотофиксацияТС" "ФотофиксацияТС0" LEFT JOIN … "ФотофиксацияТСИсточник0"."primaryKey") "STORMGENERATEDQUERY" */

Запрос исполнился и выдал результат

Пути решения

Скобки добавляются вот тут: https://github.com/Flexberry/NewPlatform.Flexberry.ORM/blob/62461760cb51684878f57f587a7f309173faf049/ICSSoft.STORMNET.Business/SQLDataService/SQLDataService.cs#L1549
Соответственно, тебе надо попробовать переопределить в ClickHouseDataService метод

string GenerateSQLSelect(LoadingCustomizationStruct customizationStruct, bool ForReadValues, out STORMDO.Business.StorageStructForView[] StorageStruct, bool Optimized)

взяв его целиком из SQLDataService и исправив только эту строку.
Важное замечание: берём исходный код ORM версии v5.0.0. Переключиться на него можно через соответствующий тег.

Исходный код

  • Нужно залогиниться в GitHub (зарегистрироваться, если нет учётной записи)
  • Сделать Fork репозитория: https://github.com/Flexberry/NewPlatform.Flexberry.ORM.ClickHouseDataService кнопка справа
  • Перейти в свой fork и сделать его git clone.
  • После этого ты можешь собрать приложение в Visual Studio (мы пользуемся версией 2019, но и более старые, наверное, тоже можно).
  • Доработки можешь смело коммитить и пушить в свой форкнутый репозиторий.
  • Если что-то непонятно, то тут есть подробности о том, как работать с гитом и не только: https://flexberry.github.io/ru/tds_module2-learn.html
  • Собранную локально сборку можно подкладывать прямо в \packages\NewPlatform.Flexberry.ORM.ClickHouseDataService.1.0.0-alpha02\lib\net45\
  • После этого надо пересобрать прикладное решение, студия подтянет при сборке новую dll и pdb из папки packages в папку bin
  • Можно подключаться под отладкой к коду ClickHouseDataService через меню Debug – Attach to process. Если это веб-сайт, то надо подлючаться к процессу iisexpress. Важно, чтобы pdb-файл соответствовал dll.
  • После выполнения исправлений в веб-интерфейсе GitHub-а надо сделать Pull Request в нашу ветку. После проверки и принятия будет собран новый NuGet-пакет.

Примерная оценка трудоёмкости

Формирование UUID'ов

Цель

Изменить алгоритм формирования с UUID4 на UUID1

Функциональные требования

Если формирование primaryKey записи производится в рамках драйвера необходимо
изменить алгоритм формирования с UUID4 на UUID1.
Генерация UUID по типу UUD4 (случайный) приводит к неэффективной работе ClickHouse со столбцами такого типа.
Необходимо изменить генерацию UUID со случайного (UUID4) на увеличивающийся UUID по типу UUID1

Требования к реализации

Как правило первичные ключи формируются на основе стандарта UUID вариант 4.
Он обеспечиват формирование случайного уникального идентификатора.

В Clickhouse случайные последовательности в столбце primaryKey очень плохо сжимаются.
Кроме того в материализованном представлении отсортированном по primaryKey при вставке
случайных последовательностей в ключе сортировки приводит к большим накладным расходам из за формирования большого количества (несколько тысяч) "частей данных".

Для решения этой проблемы необходимо при формировании primaryKey использовать
инкрементальный UUID в котором каждый последующий UUID содержит бОльшую часть символов предыдущего.

Для этой цели более всего подходит UUID версии 1,
так как формируется на основе текущего времени.

Правда в стандартной реализации он не носит инкрементального характера, так как
сначала последовательности в UUID записывается time_low, а затем time_mid.

Для обеспечения инкрементальности необходмо в начало UUID (первые 8 и 4 байта)
разместить постоянный идентификатор node (последние 12 байт).
А на место этого идентификатора последовательно поместить

  • 4 байта time_mid
  • 8 байт time_low

2-я и третья четверка байт остается на месте, так как они хранят флаги M и N
идентифицирующие версию UUID1.

На языке Python данная операция выглядит так:

ss=str(uuid.uuid1()).split('-')
primarykey = uuid.UUID('-'.join([ss[4][0:8],ss[4][8:],ss[2],ss[3],ss[1]+ss[0]])

Использование такого UUID существенно сокращает накладные расходы в ClickHouse.

Исходный код

Проект на GitHub: https://github.com/Flexberry/NewPlatform.Flexberry.ORM.ClickHouseDataService
Ветка: master

Примерная оценка трудоёмкости

16 часов

Полезные ссылки, скриншоты

Выбор подходящей таблицы при запросе данных SELECT

Цель

Обеспечить при запрсое данных (SELECT) выбор таблицы с нужными параметрами сортировки

Функциональные требования

В ClickHouse для ускорения выборки данных (SELECT) по разным ключам на основе одной "большой" таблицы, отсортированной по одним ключам создаюются материализованные предсталения, отсортированные по другим ключам. Данные материализованные представления играют роль индексов в обычных реляционных базах.
При выборке данных необходимо проанализировать имена столбцов в условии WHERE и для выборки данных использовать представление, отсортированное по столбцам содержащихся в условии WHERE.
Это обеспечивает существенное сокращения времени получения записей, так как существенно сокращается объем сканируемых записей.

Примерная оценка трудоёмкости

40 часов

Полезные ссылки, скриншоты

Добавление в запрос SELECT модификатора FINAL для таблиц типа VersionedCollapsingMergeTree

Цель

Добавление в запрос SELECT модификатора FINAL для таблиц типа VersionedCollapsingMergeTree

Функциональные требования

Для корректируемых таблиц типа VersionedCollapsingMergeTree, CollapsingMergeTree для исключения удаляемых записей необходимо добавлять после имени таблицы в FROM <имя_таблицы> ... модификатор FINAL: FROM <имя_таблицы> FINAL ...
Этот способ не рекомендуют использовать для "больших" таблиц и предлагают использовать группировку по ключам сортировки GROUP BY с модификацией списка выбираемых столбцов, но этот способ сложен в реализации.
Будем надеяться, что в последующих релизах ClickHouse эту проблему решат.
По крайней мере в TODO на 2020 год эта тема обозначена.

Полезные ссылки, скриншоты

Поддержка буферизации при добавлении данных

Цель

Обеспечить поддержку буферизации на уровне сервиса данных

Функциональные требования

При добавлении информации в таблицы ClickHouse необходимо буферизировать данные,
так как в противном случае вставки будут неэффективными.
Обычно для этих целей используются proxy-сервера. Но все они к сожалению поддерживают только HTTP-интерфейс.
У нас же драйвер использует Native TCP интерфейс.
Поэтому задача буферизации данных в настоящее время ложится на приложение.
Необходимо реализовать простой механизм формировния буфера записей по двум параметрам:

  • времени формирование буфера
  • число (или объем) записей в буфере
    После исчерпания одного из параметров накопленный буфер передается ClickHouse в виде
    INSERT ... VALUES (запись1), (запись2,)...

Проект на GitHub: https://github.com/Flexberry/NewPlatform.Flexberry.ORM.ClickHouseDataService
Ветка: master

Аналоги, примеры реализации

Примерная оценка трудоёмкости

16 часов

Downgrade ORM to 5.0

Цель

Требуется опустить версию ORM до релизной 5.0

Функциональные требования

Нужно исправить код в соответствии с внутренним API версии 5.0, поскольку 5.1 ещё не вышла.

Требования к реализации

DataService должен продолжать работать.

Примерная оценка трудоёмкости

2 ч.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.