Ожидайте неожиданного…

Я большой поклонник https://greatexpectations.io и имел возможность и удовольствие использовать эту фантастическую библиотеку в нескольких проектах. Я хотел бы поделиться с вами изюминкой и возможностями, которые появятся с https://greatexpectations.io, когда вы, мой дорогой читатель, решите попробовать ее. В качестве презентационного слоя я решил использовать #FastAPI, поскольку в настоящее время это мой любимый фреймворк python.

В этом примере интеграции я прибил большой набор данных ожиданий SqlAlchemyDataset в качестве основного компонента и построил вокруг него REST API, который легко подключается к любому другому проекту как отдельный микросервис.

В эти дни мы находимся в режиме ожидания неожиданностей. Я думаю, что то же самое происходит с данными, которые мы собираем, и с любыми другими данными. Они растут, а мы не знаем, почему. Мы не знаем, как их использовать — мы не знаем, нужны ли они нам. Более или менее, мы не знаем, чего мы не знаем 🙂 Но решение есть: нам нужно научиться задавать вопросы или узнать, каковы наши ожидания в контексте данных, которыми мы располагаем. И вот https://greatexpectations.io с набором уже сформированных вопросов/ожиданий здесь: https://greatexpectations.io/expectations/ выходит на сцену.

Вы спросите, где разница? Как пользователь я могу выбрать визуальный клиент на свой вкус и подключить его к sql базе данных. Начать читать данные или даже писать sql, чтобы узнать о данных. Здесь я пытаюсь немного оспорить это: Сколько времени уйдет на чтение всех этих таблиц и данных? Это выполнимо? Сколько sql-запросов вам нужно написать, запустить и проверить, чтобы ответить на ваши вопросы? Нужно ли нам всем знать магию sql? Ну, иногда это может быть простой подсчет строк, выполняемый каждый день, но, честно говоря, очень маловероятно, что в наши дни данные будут такими же простыми.

Давайте попробуем другой подход.

Настройка проекта.

Перед началом работы необходимо запустить docker.

Далее клонируйте репозиторий по этому адресу: https://github.com/grillazz/fastapi-greatexpectations.

После получения репозитория выполните следующие шаги по настройке:

  1. make build загрузит все базовые образы docker и зависимости проекта и соберет локальные образы docker.
  2. make up запустит контейнеры docker локально
  3. make feed_db загрузит тестовые данные в базу данных.

О проверке базы данных

Как уже упоминалось ранее, предполагается, что мы не знаем наших данных, и нам нужно немного изучить то, что там находится, чтобы получить информацию о таких объектах, как схемы, базы данных и таблицы/столбцы. Для этого у нас есть три конечные точки:

curl -X 'GET' 'http://0.0.0.0:8585/v1/database/schemas' -H 'accept: application/json'
Войти в полноэкранный режим Выйти из полноэкранного режима

Этот вызов возвращает список схем баз данных. Мы хотим иметь нашу схему shakespeare в качестве контейнера для образца потока данных. Поэтому ответ должен выглядеть так, как показано ниже:

[
 "information_schema",
 "public",
 "shakespeare"
]
Вход в полноэкранный режим Выйти из полноэкранного режима

Далее, имея на руках схему, мы можем вызвать другую конечную точку, чтобы получить список вызываемых таблиц:

curl -X 'GET' 'http://0.0.0.0:8585/v1/database/tables?sql_db_schema=shakespeare' -H 'accept: application/json'
Войти в полноэкранный режим Выйти из полноэкранного режима

В результате этого вызова мы получим список доступных таблиц в схеме Shakespeare:

[
  "wordform",
  "work",
  "chapter",
  "character",
  "character_work",
  "paragraph"
]
Войти в полноэкранный режим Выход из полноэкранного режима

И, наконец, мы можем проверить цель/таблицу, чтобы проверить, как она построена и какие типы данных она содержит, вызвав:

curl -X 'GET' 'http://0.0.0.0:8585/v1/database/columns?database_schema=shakespeare&schema_table=chapter' -H 'accept: application/json'
Войти в полноэкранный режим Выйти из полноэкранного режима

Поскольку мы выбрали таблицу главы, мы ожидаем следующий ответ, который обслуживается мета-столбцами SqlAlchemyDataset:

[
  {
    "name": "id",
    "type": {},
    "nullable": false,
    "default": null,
    "autoincrement": false,
    "comment": null
  },
  {
    "name": "work_id",
    "type": {
      "length": 32,
      "collation": null,
      "_expect_unicode": false,
      "_expect_unicode_error": null,
      "_warn_on_bytestring": false
    },
    "nullable": false,
    "default": null,
    "autoincrement": false,
    "comment": null
  },
  {
    "name": "section_number",
    "type": {},
    "nullable": false,
    "default": null,
    "autoincrement": false,
    "comment": null
  },
  {
    "name": "chapter_number",
    "type": {},
    "nullable": false,
    "default": null,
    "autoincrement": false,
    "comment": null
  },
  {
    "name": "description",
    "type": {
      "length": 256,
      "collation": null,
      "_expect_unicode": false,
      "_expect_unicode_error": null,
      "_warn_on_bytestring": false
    },
    "nullable": false,
    "default": null,
    "autoincrement": false,
    "comment": null
  }
]
Войти в полноэкранный режим Выйти из полноэкранного режима

Время ожидания / опроса / проверки данных

Прежде чем мы начнем сохранять наборы ожиданий и запускать валидации, есть возможность попробовать. Мы можем запустить каждое ожидание без затрат и дополнительных накладных расходов — мы можем назвать это песочницей ожиданий. Выбрав таблицу/цель и решив протестировать одно из ожиданий, определенных здесь https://greatexpectations.io/expectations/, мы можем запустить вызов:

curl -X 'POST' 
'http://0.0.0.0:8585/v1/expectation/try/expect_table_row_count_to_equal?database_schema=shakespeare&schema_table=chapter' 
-H 'accept: application/json' 
-H 'Content-Type: application/json' 
-d '{"value":100}'
Войти в полноэкранный режим Выйти из полноэкранного режима

Что здесь происходит. Мы решили проверить, имеет ли таблица chapter в схеме shakespeare 100 строк, используя expect_table_row_count_to_equal, и получили ответ:

{
  "success": false,
  "expectation_config": {
    "_expectation_type": "expect_table_row_count_to_equal",
    "_kwargs": {
      "value": 100,
      "result_format": "BASIC"
    },
    "_raw_kwargs": null,
    "meta": {},
    "success_on_last_run": null,
    "_ge_cloud_id": null,
    "_expectation_context": null
  },
  "result": {
    "observed_value": 945
  },
  "meta": {},
  "exception_info": {
    "raised_exception": false,
    "exception_traceback": null,
    "exception_message": null
  }
}
Войдите в полноэкранный режим Выход из полноэкранного режима

Похоже, мы ошиблись, и реальный результат равен 945. Попробуем еще раз запустить обновленный вызов:

curl -X 'POST' 
'http://0.0.0.0:8585/v1/expectation/try/expect_table_row_count_to_equal?database_schema=shakespeare&schema_table=chapter' 
-H 'accept: application/json' 
-H 'Content-Type: application/json' 
-d '{"value":945}'
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь тот же тест с новым значением 945 проходит успешно:

{
  "include_rendered_content": false,
  "success": true,
  "expectation_config": {
    "_expectation_type": "expect_table_row_count_to_equal",
    "_kwargs": {
      "value": 945,
      "result_format": "BASIC"
    },
    "_raw_kwargs": null,
    "meta": {},
    "success_on_last_run": null,
    "_ge_cloud_id": null,
    "_expectation_context": null,
    "_include_rendered_content": false
  },
  "result": {
    "observed_value": 945
  },
  "meta": {},
  "exception_info": {
    "raised_exception": false,
    "exception_traceback": null,
    "exception_message": null
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Еще один тест на ожидание того, что значения столбцов не будут нулевыми. Мы ожидаем, что для столбца description в главе таблицы не будет нулевых значений:

curl -X 'POST' 
'http://0.0.0.0:8585/v1/expectation/try/expect_column_values_to_not_be_null?database_schema=shakespeare&schema_table=chapter' 
  -H 'accept: application/json' 
  -H 'Content-Type: application/json' 
  -d '{"column":"description"}'
Войти в полноэкранный режим Выход из полноэкранного режима

И снова мы ошибаемся, так как почти 18% значений в description в таблице chapter имеют нулевое значение:

{
  "success": false,
  "expectation_config": {
    "_expectation_type": "expect_column_values_to_not_be_null",
    "_kwargs": {
      "column": "description",
      "result_format": "BASIC"
    },
    "_raw_kwargs": null,
    "meta": {},
    "success_on_last_run": null,
    "_ge_cloud_id": null,
    "_expectation_context": null,
    "_rendered_content": null
  },
  "result": {
    "element_count": 945,
    "unexpected_count": 169,
    "unexpected_percent": 17.883597883597886,
    "unexpected_percent_total": 17.883597883597886,
    "partial_unexpected_list": []
  },
  "meta": {},
  "exception_info": {
    "raised_exception": false,
    "exception_traceback": null,
    "exception_message": null
  },
  "rendered_content": null
}
Войти в полноэкранный режим Выйти из полноэкранного режима

это еще не конец…

Есть несколько суперспособностей за сценой, таких как pydantic или sqlalchemy, но вы можете понять это, прочитав код в репозитории здесь: https://github.com/grillazz/fastapi-greatexpectations.

Я все еще работаю над этим, и вы можете ожидать следующего примера использования в ближайшее время с более реальными данными и другим sql-провайдером.

Это также может работать с swagger ui на http://0.0.0.0:8585/docs.

Тестирование данных происходит из: https://github.com/catherinedevlin/opensourceshakespeare

Картинка для заголовка взята с:
https://www.behance.net/martamiazek

продолжение следует…

Оцените статью
devanswers.ru
Добавить комментарий