Header всему голова
.
Кому не знакомы странные наименования столбцов в таблицах, выгрузках или API, например,
.
ps: все же переименовывают при помощи
.
Попробуем автоматизировать этот процесс. На помощь нам придут замечательные регулярные выражения (тот самый модуль
.
Создаем функцию
- разделяет имена по заглавной букве
- переводит написание через нижнее подчеркивание
- переводит слова в LOWER CASE
Пользуйстесь наздоровье🙌
.
А вообще регулярки - это очень мощно, рекомендую обязательно ознакомится с фукнционалом модуля
- классная статья
- моя настольная книга
#regex #cameltosnake #code
.
Кому не знакомы странные наименования столбцов в таблицах, выгрузках или API, например,
deviceId или dReleaseDate. И каждый раз приходится ручками переименовывать, когда их 2-3 еще терпимо, но когда полей 20+, уже к 10 появляется 🤮.
ps: все же переименовывают при помощи
df.rename(columns={old_column_name: new_column_name}) 😉.
Попробуем автоматизировать этот процесс. На помощь нам придут замечательные регулярные выражения (тот самый модуль
re который ты обходил стороной и боялся как серебряной пули).
Создаем функцию
camel_to_snake, которая:- разделяет имена по заглавной букве
- переводит написание через нижнее подчеркивание
- переводит слова в LOWER CASE
import re.
def camel_to_snake(name):
name = re.sub('(.)([A-Z][a-z]+|[А-Я][а-я]+)', r'\1_\2', name)
return re.sub('([a-z]|[а-я])([A-Z]|[А-Я])', r'\1_\2', name).lower()
Пользуйстесь наздоровье🙌
.
А вообще регулярки - это очень мощно, рекомендую обязательно ознакомится с фукнционалом модуля
re:- классная статья
- моя настольная книга
#regex #cameltosnake #code
Хабр
Регулярные выражения в Python от простого к сложному. Подробности, примеры, картинки, упражнения
Регулярные выражения в Python от простого к сложному Решил я давеча моим школьникам дать задачек на регулярные выражения для изучения. А к задачкам нужна какая-нибудь теория. И стал я искать хорошие...
🔥5
Секреты 🐼as
.
А вы замечали, что пишите неэффективный\плохочитаемый (подставить любимое) код🤔
.
Нередко это связано с устоявшимися конструкциями, которые вы где-то увидели, набили на них руку или просто так было, когда вы изучали
.
Одна из задач в ML создание новых признкаков, при изучении временных рядов часто используется такой признак как moving average. При добавлении его необходимо исключить лик целевой, тк текущее значение входит в окно.
.
Нередко встречается такой код:
.
Исключили лишний метод, использовали встроенные аргументы - good work🤝
#code #pandas #refactor
.
А вы замечали, что пишите неэффективный\плохочитаемый (подставить любимое) код🤔
.
Нередко это связано с устоявшимися конструкциями, которые вы где-то увидели, набили на них руку или просто так было, когда вы изучали
pandas==0.23😎.
Одна из задач в ML создание новых признкаков, при изучении временных рядов часто используется такой признак как moving average. При добавлении его необходимо исключить лик целевой, тк текущее значение входит в окно.
.
Нередко встречается такой код:
df['ma'] = df['column'].shift().rolling().mean()Здесь
shift выполняет роль, исключающую текущее значение целевой (сдвигаем весь ряд на 1 позицию в будущее). В целом код понятен но перегружен дополнительным методом. Если заглянуть в доку к методу rolling то разработчики уже учли эту возможную проблему, а нам остается только воспользоваться:df['ma'] = df['column'].rolling(closed='left').mean()При такой опции
closed='left' - последнее значение в окне исключается из расчета, тем самым не будет создан лик целевой..
Исключили лишний метод, использовали встроенные аргументы - good work🤝
#code #pandas #refactor
Идеальные данные для pandas
.
В этих данных не будет дубликатов, пропусков, некорректных значений и всех остальных наших проблем с данными🤩
.
Заинтригованы? Я нашел их - берите и пользуйтесь панда-данные
.
Попробуем решить одну из задачек - cloud of words для кого, конечно же, По😉
.
Здесь ссылка на google-colab. Осторожно основа кода сгенерирована ChatGPT😱
.
#data #code #practice
.
В этих данных не будет дубликатов, пропусков, некорректных значений и всех остальных наших проблем с данными🤩
.
Заинтригованы? Я нашел их - берите и пользуйтесь панда-данные
.
Попробуем решить одну из задачек - cloud of words для кого, конечно же, По😉
.
Здесь ссылка на google-colab. Осторожно основа кода сгенерирована ChatGPT😱
.
#data #code #practice
#WeAreGRUT
.
Немного личного в публичное
А как вы проводите свои выходные😜
.
У меня запланированы весёлые беговые старты на фестивале GRUT🪵
.
В этом году нет одной дистанции, а сразу три:
1⃣0⃣km HardHight
5⃣km Sprint
T2⃣0⃣km в основной день
.
Да, пребудет с вами сила🙌
#grut #run
.
Немного личного в публичное
А как вы проводите свои выходные😜
.
У меня запланированы весёлые беговые старты на фестивале GRUT🪵
.
В этом году нет одной дистанции, а сразу три:
1⃣0⃣km HardHight
5⃣km Sprint
T2⃣0⃣km в основной день
.
Да, пребудет с вами сила🙌
#grut #run
👍1🔥1
🤨 Пиу-пиу
.
Разрезаем пустоту информационного пространства. Последний месяц прошёл в активном поиске работы, будет серия постов про вопросы с собеседований.
.
Текущий мой вектор - data engineering👨🔧 И вопросы соответствующие, но будет и практическая часть с задачками, соответственно всеми любимый SQL😜
.
Буду выкладывать задачки, чтобы вы могли подумать, а потом прикладывать своё решение в моменте (возможно, дополню его, тем, что можно было бы улучшить)
.
Разрезаем пустоту информационного пространства. Последний месяц прошёл в активном поиске работы, будет серия постов про вопросы с собеседований.
.
Текущий мой вектор - data engineering👨🔧 И вопросы соответствующие, но будет и практическая часть с задачками, соответственно всеми любимый SQL😜
.
Буду выкладывать задачки, чтобы вы могли подумать, а потом прикладывать своё решение в моменте (возможно, дополню его, тем, что можно было бы улучшить)
❤4🔥3👍1
А пока вы вспоминаете SQL
.
Принес вам забавный (ну не очень) случай из работы.
.
На скрине выше:
- первое поле есть в таблице
- второго нет (подчеркнуто красным)
.
А где же разница? А разница в букве
.
Написать код, забирающий данные - 15 минут, найти такую ошибку - бесценно❤️
.
Принес вам забавный (ну не очень) случай из работы.
.
На скрине выше:
- первое поле есть в таблице
- второго нет (подчеркнуто красным)
.
А где же разница? А разница в букве
C - в существующем поле она кириллическая🤷♂️🤯.
Написать код, забирающий данные - 15 минут, найти такую ошибку - бесценно❤️
🥴2
Задача 1️⃣
.
На очереди первая задачка по SQL, кажется, что она самая популярная,она была в двух вариантах:
1. Даны следующие таблицы
.
Ответы оставляем в комментариях👇 ps: тут конечно могут помочь диаграммы Венна (кружочки), но они имеют изъян.
#вопросы #собес #sql
.
На очереди первая задачка по SQL, кажется, что она самая популярная,она была в двух вариантах:
1. Даны следующие таблицы
a - 5 rowsВыполняется такой запрос:
b - 10 rows
select count(*)2. Даны таблицы t1 и t2
from a
unknown join b on unknown (a.a=b.b)
Какое максимальное и минимальное количество может быть для разных join? Примечание: значения в таблицах уникальны.
t1 t2
1 3
2 4
3 5
4 6
5 7
Что получится при разных видах JOIN
.
Ответы оставляем в комментариях👇 ps: тут конечно могут помочь диаграммы Венна (кружочки), но они имеют изъян.
#вопросы #собес #sql
Задачки 2️⃣ и 3️⃣
+ дополнительный вопрос от меня
——————————————————
.
Жду ваших решений в комментариях и помните, у задачки необязательно есть одно единственное решение😉
#вопросы #собес #sql
Дана таблица:
CREATE TABLE IF NOT EXISTS prices (
id bigint not null,
price int4 not null,
dt date not null
);
Пример данных:
id price dt
1 100 2021-01-01
1 110 2021-05-05
В таблице prices хранятся данные по ценам товаров. В этой таблице есть другие цены и другие товары, эти приведены для примера.
При изменении цены записывается новая строка с датой начиная с которой это цена действует.
Цена действует до тех пор, пока она не сменится другой ценой.
Надо написать параметризованный запрос, который по id и dt вернет цену товара на этот день.
Например:id=1, dt=2021-01-02 => price=100id=1, dt=2021-06-01 => price=110.
+ дополнительный вопрос от меня
Какой механизм реализован в этой таблице?——————————————————
Дана таблица Client (id, email, phone)
1. Найти все email которые встречаются в таблице более 2х раз.
2. Вывести id, email, email_дуплицирован(1,0)
☝️1 и 2 - два разных запроса
.
Жду ваших решений в комментариях и помните, у задачки необязательно есть одно единственное решение😉
#вопросы #собес #sql
Задача 4️⃣ (в двух частях)
.
.
Жду ваших верных решений😎
#вопросы #собес #sql
.
Дана таблица:
CREATE TABLE IF NOT EXISTS deliveries (
id bigint not null,
dt date not null,
id_supplier bigint not null,
id_product bigint not null,
quantity int4 not null,
price decimal(16, 4)
);
Пример данных:
id dt id_supplier id_product quantity price
1 2021-01-01 2 134 5 10.5
2 2021-05-05 1 135 10 11.0
Задача 2.1
В таблице хранятся данные о поставках, каждая поставка имеет:
свой уникальный id, дату совершения поставки dt, данные о поставщике id_supplier и товаре id_product, количестве штук товара в поставке quantity, цене одной штуки price.
Необходимо найти поставщика, который поставил нам товаров на наибольшую сумму денег.
Задача 2.2
Дополнительно дан справочник:
CREATE TABLE IF NOT EXISTS supplier (
id bigint not null,
name VARCHAR(200) not null
);
Пример данных:
id name
1 Поставщик1
2 Поставщик2
Как найти поставщиков которые ничего не поставляли, если рядом есть справочник поставщиков?
.
Жду ваших верных решений😎
#вопросы #собес #sql
Задача 5️⃣
.
Продолжаем серию SQL задачек, на очереди аналитическая задачка.
.
.
Дерзайте, задачку точно можно решить не одним способом😉 Используйте все ваши знания и творческий подход😎
#вопросы #собес #sql
.
Продолжаем серию SQL задачек, на очереди аналитическая задачка.
.
Посчитать среднее время нахождения в статусе "Подтверждён" , за которым следовал статус "Доставлен" для заказов , созданных в этом году.
-- Таблица, со статусами заказа
create table OrderStatusChangeLog
(
order_id INTEGER
, status_id INTEGER
, time_changed DATETIME
);
comment on column OrderStatusChangeLog.order_id is 'ID заказа';
comment on column OrderStatusChangeLog.status_id is 'ID статуса заказа';
comment on column OrderStatusChangeLog.time_changed is 'Время изменения заказа';
Пример (сэмпл) данных в таблице:
+--------+---------+-------------------+
|order_id|status_id|time_changed |
+--------+---------+-------------------+
|14324 |1 |01.05.2022 10:00:01|
|14324 |2 |01.05.2022 10:25:17|
|14324 |10 |01.05.2022 10:30:55|
|14324 |7 |01.05.2022 10:31:24|
|14324 |10 |01.05.2022 15:30:54|
|14324 |5 |04.05.2022 12:22:32|
|1468 |1 |01.05.2022 10:00:01|
|1468 |2 |01.05.2022 11:25:23|
|1468 |10 |01.05.2022 11:30:48|
|67825 |1 |01.05.2022 10:00:01|
|67825 |2 |01.05.2022 10:25:44|
|67825 |10 |01.05.2022 10:30:05|
|67825 |5 |08.05.2022 16:32:49|
+--------+---------+-------------------+
-- Таблица-справочник статусов
create table OrderStatus
(
status_id INTEGER
, status_name VARCHAR(255)
);
comment on column OrderStatus.status_id is 'ID статуса заказа';
comment on column OrderStatus.status_name is 'Наименование статуса заказа';
Пример (сэмпл) данных в таблице:
+---------+-----------+
|status_id|status_name|
+---------+-----------+
|1 |Новый |
|2 |Оплачен |
|10 |Подтверждён|
+---------+-----------+
-- Таблица с заказами
create table Orders
(
order_id INTEGER PRIMARY KEY
, time_created DATETIME
, client_id INTEGER
, status_id INTEGER
);
comment on column Orders.order_id is 'ID заказа';
comment on column Orders.time_created is 'Время создания заказа';
comment on column Orders.client_id is 'ID клиента';
comment on column Orders.status_id is 'ID текущего статуса заказа';
Пример (сэмпл) данных в таблице:
+--------+-------------------+---------+---------+
|order_id|time_created |client_id|status_id|
+--------+-------------------+---------+---------+
|1468 |01.05.2022 10:00:01|234 |10 |
|14324 |01.05.2022 10:00:01|738294 |5 |
|3421987 |10.03.2021 19:03:55|761285 |5 |
+--------+-------------------+---------+---------+
.
Дерзайте, задачку точно можно решить не одним способом😉 Используйте все ваши знания и творческий подход😎
#вопросы #собес #sql
👍2
Задачки с собесов - Python
.
В работе дата инженера нередко приходится тянуть данные из API, в работе с ним помогает Python, поэтому есть и задачки по нему. Встречаем первую:
.
При решении внимательно приглядитесь к функции
.
Пока решаете, вспомните с какими "чудесными" API вам приходилось работать, пишите их в комментах.
#вопросы #собес #python
.
В работе дата инженера нередко приходится тянуть данные из API, в работе с ним помогает Python, поэтому есть и задачки по нему. Встречаем первую:
Ответ от API:
response = '''
{
"trace_id": "d6518bbb-b47b-4d1b-931e-74013148872d",
"type": "ADD",
"data": [
{
"id": 464612,
"timestamp": "2023-05-04T09:24:57Z",
"is_rejected": false,
"reason": null,
"values": [13.4, 64.7, 12]
},
{
"id": 464612,
"timestamp": "2023-05-04T10:32:15Z",
"is_rejected": false,
"reason": null,
"values": [77.3, 7.6, 10]
},
{
"id": 74641123,
"timestamp": "2023-05-04T05:23:13Z",
"is_rejected": true,
"reason": "Code 53",
"values": [45.2, 0.5, 0]
}
]
}
'''
В ответе от API не хватает поля name, его можно получить вызвав функцию get_name_by_id:
def get_name_by_id(id: int) -> str:
from random import randrange
from time import sleep
sleep(1)
box_number = randrange(0, 1000) // len(str(id))
return f"Box {box_number}"
.
При решении внимательно приглядитесь к функции
get_name_by_id, неспроста там есть некоторые моменты☝️.
Пока решаете, вспомните с какими "чудесными" API вам приходилось работать, пишите их в комментах.
#вопросы #собес #python
❤2👍1🔥1
А такое даже не грешно запостить: смотрите как изменилась картина тулзов для дата инженеров🙈
Forwarded from 🔋 Труба данных (Simon Osipov)
How it started (~2012) VS How it is going (2023)
Кстати, текущую карту можно интерактивно покликать вот тут https://mad.firstmark.com/
@ohmydataengineer
Кстати, текущую карту можно интерактивно покликать вот тут https://mad.firstmark.com/
@ohmydataengineer
🔥1
https://bar-or-pie.dianov.org/result-1300.html
Бар о пай
📈Это однозначно лучшее про датавиз-гигиену
.
Пройдите тест и узнайте:
- в каких случаях стоит использовать цветовую кодировку, а когда нет
- когда обводка это зло
- когда следует повернуть ваш барплот
- или когда не следует подписывать все числа на графике
.
И наконец ответьте себе на главный вопрос: Bar or Pie😉
ps: а еще там есть ссылки, в которых более подробно изложена та или иная идея
.
#plot #data #bar #pie
Бар о пай
📈Это однозначно лучшее про датавиз-гигиену
.
Пройдите тест и узнайте:
- в каких случаях стоит использовать цветовую кодировку, а когда нет
- когда обводка это зло
- когда следует повернуть ваш барплот
- или когда не следует подписывать все числа на графике
.
И наконец ответьте себе на главный вопрос: Bar or Pie😉
ps: а еще там есть ссылки, в которых более подробно изложена та или иная идея
.
#plot #data #bar #pie
bar-or-pie.dianov.org
1300 очков набрал в датавиз-игре
Короткий тест с основными принципами визуализации данных.
❤3👍1
😎А вы уже еBASH.....
.
Не перестаю удивляться магии линукса и простых (но это не точно) консольных команд.
.
Разбираясь с уткойпо-пекински 🦆 (про неё тоже будет пост, довольно интересная альтернатива sqlite3, особенно если хочется практиковать SQL) в доке обнаружил утилиту для построения графиков в терминале youplot 😈. В кратком tutorial можно найти довольно приличный набор графиков:
- столбчатые
- линейные
- гистограммы или графики плотности
- scatterplot
- boxplot
Кажется, для базового анализа выше крыши, так что теперь разведывательный анализ можно выполнять без Python😁
.
Конечно, чтобы построить график нужно не бояться терминала (вообще кажется, в нем можно сделать всё и немножечко больше).
.
Вот некоторые сниппеты:
Данные из файла на github:
В общем изучаем магию🧙♀️
А вы знаете что-то хитрое в linux-терминале?
#bash #duckdb #youplot
.
Не перестаю удивляться магии линукса и простых (но это не точно) консольных команд.
.
Разбираясь с уткой
- столбчатые
- линейные
- гистограммы или графики плотности
- scatterplot
- boxplot
Кажется, для базового анализа выше крыши, так что теперь разведывательный анализ можно выполнять без Python😁
.
Конечно, чтобы построить график нужно не бояться терминала (вообще кажется, в нем можно сделать всё и немножечко больше).
.
Вот некоторые сниппеты:
<code class="language-bash"># данные из Python
echo -e "from numpy import random;"
"n = random.randn(25000);"
"print('\\n'.join(str(i) for i in n))"
| python3
| uplot hist --nbins 51
Данные из файла на github:
<code class="language-bash">curl -s https://raw.githubusercontent.com/urevoleg/example-direct-access/main/kinopoisk/kinopoisk_parsing.csv | awk -F';' '{print $20}' | uplot hist --nbins 20В общем изучаем магию🧙♀️
А вы знаете что-то хитрое в linux-терминале?
#bash #duckdb #youplot
🔥1
🔥По горячим следам
.
Случился стандартный рабочий кейс: надо затащить несколько внешних таблиц в клик.
Источник: Postgres
Сущность: N вьюх (у одной из под капотом было около десятка JOIN 🥶, дадим ей имя вьюха
История умалчивает подробности и даже почему выбран такой способ загрузки: целевая таблица полностью перегружается каждый день.
.
Работа шла стандартным флоу (практикую частичное решение задач):
- написал даг с коннектом к источнику
- таски для создания инфры
- несколько таск групп с небольшим селектом из источника (проверить, что всё ок и источник отдает данные)
- заварил 🫖 и стал налюдать за даграном
.
Всё шло хорошо до момента тестирования вьюхи G. В логах вижу инфра создается, как только дело доходит до забора данных, то таска ждет и падает по
.
В процессе обсуждения с разработчиком со стороны источника выяснилось:
- про десятки JOIN
- там в таблице 10+млн строк
- .....
.
Но тут я подумал: ведь я же батчами забираю, причем здесь млн строк🤔.
.
Код для загрузки батчами тривиален:
.
Крутил, вертел никак, надо идти курить доку (тимлид подкинул про именованные курсоры). И от тут истина и открылась, если делать так как выше, то:
-
- полные данные передаются на клиент
- и батчи получаются на стороне клиента - то есть у нас клиентский курсор
И естественно дождаться не получается пока собирутся 10+млн строк.
.
Из доки psycopg2 узнал про реализацию серверного курсора (тот который будет формировать батчи на стороне сервера и отдавать их). Для организиации серверного курсора меняем код, использовать красивую pandas-обертку уже не получится:
.
Бинго, теперь батчи отдаются по мере готовности и не нужно ждать сбора всех данных - пошло чтение данных. Далее я дописал загрузку в Clickhouse.
.
ps: на источнике окаалось 36+млн строк 🤨
#case #work #psycopg2 #def
.
Случился стандартный рабочий кейс: надо затащить несколько внешних таблиц в клик.
Источник: Postgres
Сущность: N вьюх (у одной из под капотом было около десятка JOIN 🥶, дадим ей имя вьюха
G)История умалчивает подробности и даже почему выбран такой способ загрузки: целевая таблица полностью перегружается каждый день.
.
Работа шла стандартным флоу (практикую частичное решение задач):
- написал даг с коннектом к источнику
- таски для создания инфры
- несколько таск групп с небольшим селектом из источника (проверить, что всё ок и источник отдает данные)
- заварил 🫖 и стал налюдать за даграном
.
Всё шло хорошо до момента тестирования вьюхи G. В логах вижу инфра создается, как только дело доходит до забора данных, то таска ждет и падает по
SIGTERM - явно что-то идет не так..
В процессе обсуждения с разработчиком со стороны источника выяснилось:
- про десятки JOIN
- там в таблице 10+млн строк
- .....
.
Но тут я подумал: ведь я же батчами забираю, причем здесь млн строк🤔.
.
Код для загрузки батчами тривиален:
<code class="language-python"><code class="language-python">import psycopg2
con = psycopg2.connect(.....)
...
for chunk in pd.read_sql(stmt, con=con, chunk_size=100500):
yield chunk
.
Крутил, вертел никак, надо идти курить доку (тимлид подкинул про именованные курсоры). И от тут истина и открылась, если делать так как выше, то:
-
stmt должно выполниться полностью на стороне сервера- полные данные передаются на клиент
- и батчи получаются на стороне клиента - то есть у нас клиентский курсор
И естественно дождаться не получается пока собирутся 10+млн строк.
.
Из доки psycopg2 узнал про реализацию серверного курсора (тот который будет формировать батчи на стороне сервера и отдавать их). Для организиации серверного курсора меняем код, использовать красивую pandas-обертку уже не получится:
<code class="language-python">import psycopg2
from psycopg2.extras import RealDictCursor
with psycopg2.connect(...) as conn:
with conn.cursor(name="It's server cursor", cursor_factory=RealDictCursor()) as cursor:
cur.execute(stmt)
chunk = cur.fetchmany(chunk_size)
while chunk:
yield pd.DataFrame(chunk)
chunk = cur.fetchmany(chunk_size)
.
Бинго, теперь батчи отдаются по мере готовности и не нужно ждать сбора всех данных - пошло чтение данных. Далее я дописал загрузку в Clickhouse.
.
ps: на источнике окаалось 36+млн строк 🤨
#case #work #psycopg2 #def
🔥6
Clickhouse-notes 📔
.
Буду делиться лайфхаками, которые использую в работе. Отмечу, что на работе клик распределенный и это накладывает некоторые ограничения или нюансы в работе ( а вы как хотели, только плюсы чтоль)
.
0️⃣Стоит отметить такой факт: клик распределенный -> нет мастер ноды -> координирует работу Zookeeper -> запросы можно выполнять как
В первом подходе организуется
.
Операции
.
Локально у меня всегда в docker запущен clickhouse (однонодовый) для экспериментов, с однонодовым в разы легче и проще, а скорость его работы, ну вы знаете 🚀
.
ps: где-то было видео со сравнением работы одного и того же запроса на Postgres и Clickhouse, найду, отправлю в комменты. Понятно что сравнение ежа со слоном, но когда я первый раз так перешел был приятно удивлен 🙃
#clickhouse #lifehacks
.
Буду делиться лайфхаками, которые использую в работе. Отмечу, что на работе клик распределенный и это накладывает некоторые ограничения или нюансы в работе ( а вы как хотели, только плюсы чтоль)
.
0️⃣Стоит отметить такой факт: клик распределенный -> нет мастер ноды -> координирует работу Zookeeper -> запросы можно выполнять как
ON CLUSTER так и на каждом хосте отдельноВ первом подходе организуется
distributed_ddl_queue, которая иногда очень долго рассасывается, при втором подходе мы обходим эту очередь, выполняя запросы на каждом хосте отдельно - это можно назвать лайфхаком номер 0.
Операции
DELETE\ UPDATE дорогие для клика (это мутации, выпоняются через ALTER TABLE) - их вообще следует избегать, используя семейство движков MergeTree. Но иногда без них нельзя, аналитикам только дай, что поделитить или поапдейтить -> копиться очередь -> её надо обходить.
Локально у меня всегда в docker запущен clickhouse (однонодовый) для экспериментов, с однонодовым в разы легче и проще, а скорость его работы, ну вы знаете 🚀
.
ps: где-то было видео со сравнением работы одного и того же запроса на Postgres и Clickhouse, найду, отправлю в комменты. Понятно что сравнение ежа со слоном, но когда я первый раз так перешел был приятно удивлен 🙃
#clickhouse #lifehacks
👍2
🚛 Как грузить в клик
.
Из ответа на вопрос в комментариях родился маленький пост.
Для загрузки данных в clickhouse в команде используем два подхода:
1️⃣ Pythonic way с использованием clickhouse_driver
Тут два метода:
-
-
Кому, что больше нравиться, встречаются ошибки с типами данных
2️⃣ Native way с использованием linux клиента clickhouse-client
Например, способом ниже загружаются csv файлы
Оба подхода используют TCP соединение.
Есть еще третий, с использованием HTTP, ниже пример bash скрипта:
Вероятно, бывает иногда полезный, пока использовать не приходилось. У 3 способа есть особенности, о них лучше почитать в доке,например, у меня завелась передача user\pass только через заголовки.
#clickhouse #de #dataload #load
.
Из ответа на вопрос в комментариях родился маленький пост.
Для загрузки данных в clickhouse в команде используем два подхода:
1️⃣ Pythonic way с использованием clickhouse_driver
Тут два метода:
-
execute-
insert_dataframeКому, что больше нравиться, встречаются ошибки с типами данных
2️⃣ Native way с использованием linux клиента clickhouse-client
Например, способом ниже загружаются csv файлы
<code class="language-shell"><code class="language-bash">cat file.csv | clickhouse-client --host=$CH_HOST --user=$CH_USER --password=$CH_PASSWORD --query="INSERT INTO $CH_SCHEMA.$CH_TABLE FORMAT CSVWithNames"
Оба подхода используют TCP соединение.
Есть еще третий, с использованием HTTP, ниже пример bash скрипта:
<code class="language-bash">#!/bin/bash
#CH
CLUSTER_NAME=
CH_HOST=192.168.55.121
CH_PORT=8123
CH_SCHEMA=stage
CH_USER=clickadmin
CH_PASSWORD=aLpjr5HMq
CH_TABLE=TMP_CURL2CH
CH_URL="http://${CH_HOST}:${CH_PORT}"
DDL_QUERY="CREATE OR REPLACE TABLE $CH_SCHEMA.$CH_TABLE
(
user_id String,
name Nullable(String),
email Nullable(String),
phone Nullable(String),
address Nullable(String),
birth_date Nullable(Date)
)
ENGINE = MergeTree
ORDER BY (birth_date, name, phone)
SETTINGS index_granularity = 8192, allow_nullable_key=1;"
echo "☠️ DDL Executing...."
echo $DDL_QUERY | curl -H "X-ClickHouse-User: $CH_USER" -H "X-ClickHouse-Key: $CH_PASSWORD" "$CH_URL?query=" --data-binary @-
CSV_FILE="src/data.csv"
# Определение запроса на загрузку данных
INSERT_QUERY="INSERT+INTO+$CH_SCHEMA.$CH_TABLE+(user_id,name,email,phone,address,birth_date)+FORMAT+CSVWithNames"
echo "🚰 Inserting data from file: $CSV_FILE...."
echo "$CH_URL?query=$INSERT_QUERY"
cat $CSV_FILE | curl --data-binary @- -H "X-ClickHouse-User: $CH_USER" -H "X-ClickHouse-Key: $CH_PASSWORD" "$CH_URL?query=$INSERT_QUERY"
Вероятно, бывает иногда полезный, пока использовать не приходилось. У 3 способа есть особенности, о них лучше почитать в доке,например, у меня завелась передача user\pass только через заголовки.
#clickhouse #de #dataload #load
GitHub
GitHub - mymarilyn/clickhouse-driver: ClickHouse Python Driver with native interface support
ClickHouse Python Driver with native interface support - mymarilyn/clickhouse-driver
👍2