dbhose-airflow 0.0.0.1__py3-none-any.whl → 0.0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dbhose_airflow/__init__.py +3 -2
- dbhose_airflow-0.0.2.0.dist-info/METADATA +197 -0
- dbhose_airflow-0.0.2.0.dist-info/RECORD +11 -0
- dbhose_airflow-0.0.2.0.dist-info/licenses/CHANGELOG.md +22 -0
- dbhose_airflow-0.0.2.0.dist-info/licenses/README.md +176 -0
- dbhose_airflow-0.0.0.1.dist-info/METADATA +0 -432
- dbhose_airflow-0.0.0.1.dist-info/RECORD +0 -11
- dbhose_airflow-0.0.0.1.dist-info/licenses/CHANGELOG.md +0 -5
- dbhose_airflow-0.0.0.1.dist-info/licenses/README.md +0 -410
- {dbhose_airflow-0.0.0.1.dist-info → dbhose_airflow-0.0.2.0.dist-info}/WHEEL +0 -0
- {dbhose_airflow-0.0.0.1.dist-info → dbhose_airflow-0.0.2.0.dist-info}/top_level.txt +0 -0
dbhose_airflow/__init__.py
CHANGED
|
@@ -30,7 +30,8 @@ __all__ = (
|
|
|
30
30
|
"MoveMethod",
|
|
31
31
|
"dbhose_dumper",
|
|
32
32
|
)
|
|
33
|
-
|
|
33
|
+
__author__ = "0xMihalich"
|
|
34
|
+
__version__ = "0.0.2.0"
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
root_path = dirname(__file__)
|
|
@@ -348,7 +349,7 @@ class DBHose:
|
|
|
348
349
|
))
|
|
349
350
|
is_avaliable, move_query = tuple(*reader.to_rows())
|
|
350
351
|
|
|
351
|
-
if not is_avaliable:
|
|
352
|
+
if not is_avaliable or not move_query:
|
|
352
353
|
error_msg = (
|
|
353
354
|
f"Method {self.move_method.name} is not available for "
|
|
354
355
|
f"{self.table_dest}. Use another method."
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dbhose_airflow
|
|
3
|
+
Version: 0.0.2.0
|
|
4
|
+
Summary: airflow class for exchanging data between DBMSs in native binary formats.
|
|
5
|
+
Home-page: https://github.com/0xMihalich/dbhose_airflow
|
|
6
|
+
Author: 0xMihalich
|
|
7
|
+
Author-email: bayanmobile87@gmail.com
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: README.md
|
|
10
|
+
License-File: CHANGELOG.md
|
|
11
|
+
Requires-Dist: apache-airflow>=2.4.3
|
|
12
|
+
Requires-Dist: native-dumper==0.3.3.0
|
|
13
|
+
Requires-Dist: pgpack-dumper==0.3.3.0
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: description
|
|
17
|
+
Dynamic: description-content-type
|
|
18
|
+
Dynamic: home-page
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
Dynamic: summary
|
|
21
|
+
|
|
22
|
+
# DBHose для Apache Airflow
|
|
23
|
+
|
|
24
|
+
```ascii
|
|
25
|
+
( )
|
|
26
|
+
( ( ) )\ ) ( ( /(
|
|
27
|
+
)\))( ' ( ( ) ( ( /( (()/( ( )\ )\()) (
|
|
28
|
+
((_)()\ ) ))\ )\ ( ( ( ))\ )\()) ( /(_)) )((_) ((_)\ ( ( ))\
|
|
29
|
+
_(())\_)() /((_) (( ) )\ )\ )\ ' /((_) (_))/ )\ (_))_ ((_)_ _((_) )\ )\ /((_)
|
|
30
|
+
\ \((_)/ /(_)) | | ((_) ((_) _((_)) (_)) | |_ ((_) | \ | _ ) | || | ((_) ((_) (_))
|
|
31
|
+
\ \/\/ / / -_) | | / _| / _ \ | ' \() / -_) | _| / _ \ | |) | | _ \ | __ | / _ \ (_-< / -_)
|
|
32
|
+
\_/\_/ \___| |_| \__| \___/ |_|_|_| \___| \__| \___/ |___/ |___/ |_||_| \___/ /__/ \___|
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Класс `DBHose` предоставляет универсальный интерфейс для переноса данных между различными источниками в Apache Airflow DAGs.
|
|
36
|
+
|
|
37
|
+
## ⚠️ Статус проекта
|
|
38
|
+
|
|
39
|
+
**Проект находится в стадии альфа-тестирования** и может содержать ошибки. Используйте с осторожностью в production-средах.
|
|
40
|
+
|
|
41
|
+
## Поддерживаемые СУБД
|
|
42
|
+
|
|
43
|
+
На данный момент работа с СУБД поддерживается только между следующими базами данных:
|
|
44
|
+
|
|
45
|
+
- **ClickHouse**
|
|
46
|
+
- **Greenplum**
|
|
47
|
+
- **PostgreSQL**
|
|
48
|
+
|
|
49
|
+
## Описание
|
|
50
|
+
|
|
51
|
+
DBHose - это инструмент для безопасного и эффективного перемещения данных между:
|
|
52
|
+
- Файлами дампов
|
|
53
|
+
- Python итераторами
|
|
54
|
+
- DataFrame (Pandas/Polars)
|
|
55
|
+
- Поддерживаемыми СУБД (ClickHouse, Greenplum, PostgreSQL)
|
|
56
|
+
|
|
57
|
+
Класс включает встроенные проверки качества данных (Data Quality) и поддерживает различные методы перемещения данных.
|
|
58
|
+
|
|
59
|
+
## Инициализация
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
DBHose(
|
|
63
|
+
table_dest: str,
|
|
64
|
+
connection_dest: str,
|
|
65
|
+
connection_src: str | None = None,
|
|
66
|
+
dq_skip_check: list[str] = [],
|
|
67
|
+
filter_by: list[str] = [],
|
|
68
|
+
drop_temp_table: bool = True,
|
|
69
|
+
move_method: MoveMethod = MoveMethod.replace,
|
|
70
|
+
custom_move: str | None = None,
|
|
71
|
+
compress_method: CompressionMethod = CompressionMethod.ZSTD,
|
|
72
|
+
timeout: int = DBMS_DEFAULT_TIMEOUT_SEC,
|
|
73
|
+
)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Параметры
|
|
77
|
+
|
|
78
|
+
- **`table_dest`** (`str`) - целевая таблица для загрузки данных
|
|
79
|
+
- **`connection_dest`** (`str`) - подключение к целевой БД (должна быть одной из поддерживаемых: ClickHouse, Greenplum, PostgreSQL)
|
|
80
|
+
- **`connection_src`** (`str`, optional) - подключение к исходной БД (если отличается от целевой)
|
|
81
|
+
- **`dq_skip_check`** (`list[str]`) - список проверок качества данных для пропуска
|
|
82
|
+
- **`filter_by`** (`list[str]`) - список колонок для фильтрации при перемещении данных
|
|
83
|
+
- **`drop_temp_table`** (`bool`) - удалять ли временную таблицу после операции (по умолчанию `True`)
|
|
84
|
+
- **`move_method`** (`MoveMethod`) - метод перемещения данных (по умолчанию `MoveMethod.replace`)
|
|
85
|
+
- **`custom_move`** (`str`, optional) - пользовательский SQL запрос для перемещения данных
|
|
86
|
+
- **`compress_method`** (`CompressionMethod`) - метод сжатия для дампов (по умолчанию `CompressionMethod.ZSTD`)
|
|
87
|
+
- **`timeout`** (`int`) - таймаут операций с БД в секундах (по умолчанию `DBMS_DEFAULT_TIMEOUT_SEC` = 300)
|
|
88
|
+
|
|
89
|
+
## Методы
|
|
90
|
+
|
|
91
|
+
### Основные методы загрузки данных
|
|
92
|
+
|
|
93
|
+
#### `from_file(fileobj: BufferedReader)`
|
|
94
|
+
Загрузка данных из файла дампа.
|
|
95
|
+
|
|
96
|
+
**Параметры:**
|
|
97
|
+
- `fileobj` (`BufferedReader`) - файловый объект для чтения дампа
|
|
98
|
+
|
|
99
|
+
#### `from_iterable(dtype_data: Iterable[Any])`
|
|
100
|
+
Загрузка данных из Python итератора.
|
|
101
|
+
|
|
102
|
+
**Параметры:**
|
|
103
|
+
- `dtype_data` (`Iterable[Any]`) - итерируемый объект с данными
|
|
104
|
+
|
|
105
|
+
#### `from_frame(data_frame: PDFrame | PLFrame)`
|
|
106
|
+
Загрузка данных из DataFrame (Pandas или Polars).
|
|
107
|
+
|
|
108
|
+
**Параметры:**
|
|
109
|
+
- `data_frame` (`PDFrame | PLFrame`) - DataFrame в формате Pandas или Polars
|
|
110
|
+
|
|
111
|
+
#### `from_dmbs(query: str | None = None, table: str | None = None)`
|
|
112
|
+
Загрузка данных из СУБД с использованием SQL запроса или прямой выгрузки из таблицы.
|
|
113
|
+
|
|
114
|
+
**Параметры:**
|
|
115
|
+
- `query` (`str`, optional) - SQL запрос для выборки данных
|
|
116
|
+
- `table` (`str`, optional) - имя таблицы для прямой выгрузки
|
|
117
|
+
|
|
118
|
+
### Вспомогательные методы
|
|
119
|
+
|
|
120
|
+
#### `create_temp()`
|
|
121
|
+
Создание временной таблицы для промежуточного хранения данных.
|
|
122
|
+
|
|
123
|
+
#### `drop_temp()`
|
|
124
|
+
Удаление временной таблицы.
|
|
125
|
+
|
|
126
|
+
#### `dq_check(table: str | None = None)`
|
|
127
|
+
Запуск проверок качества данных.
|
|
128
|
+
|
|
129
|
+
**Параметры:**
|
|
130
|
+
- `table` (`str`, optional) - имя исходной таблицы для сравнения данных
|
|
131
|
+
|
|
132
|
+
#### `to_table()`
|
|
133
|
+
Перемещение данных из временной таблицы в целевую.
|
|
134
|
+
|
|
135
|
+
## Пример использования в DAG
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
from datetime import datetime
|
|
139
|
+
|
|
140
|
+
from airflow import DAG
|
|
141
|
+
from airflow.operators.python import PythonOperator
|
|
142
|
+
from dbhose_airflow import (
|
|
143
|
+
DBHose,
|
|
144
|
+
MoveMethod,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
def transfer_data():
|
|
148
|
+
# Перенос данных из PostgreSQL в ClickHouse
|
|
149
|
+
dbhose = DBHose(
|
|
150
|
+
table_dest="target_table",
|
|
151
|
+
connection_dest="clickhouse_conn",
|
|
152
|
+
connection_src="postgres_conn",
|
|
153
|
+
move_method=MoveMethod.replace
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
dbhose.from_dmbs(table="source_table")
|
|
157
|
+
|
|
158
|
+
with DAG('data_transfer_dag', start_date=datetime(2025, 10, 27)) as dag:
|
|
159
|
+
transfer_task = PythonOperator(
|
|
160
|
+
task_id='transfer_data',
|
|
161
|
+
python_callable=transfer_data
|
|
162
|
+
)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Ограничения альфа-версии
|
|
166
|
+
|
|
167
|
+
- Поддерживаются только ClickHouse, Greenplum и PostgreSQL
|
|
168
|
+
- Возможны ошибки при работе с большими объемами данных
|
|
169
|
+
- API может изменяться в будущих версиях
|
|
170
|
+
- Не все функции могут быть полностью протестированы
|
|
171
|
+
- Документация может быть неполной
|
|
172
|
+
|
|
173
|
+
## Особенности
|
|
174
|
+
|
|
175
|
+
- **Автоматическое создание временных таблиц** - данные сначала загружаются во временную таблицу
|
|
176
|
+
- **Проверки качества данных** - встроенные проверки перед финальным перемещением
|
|
177
|
+
- **Гибкие методы перемещения** - поддержка различных стратегий обновления данных
|
|
178
|
+
- **Поддержка множества источников** - файлы, DataFrame, СУБД
|
|
179
|
+
- **Логирование операций** - детальное логирование всех этапов процесса
|
|
180
|
+
|
|
181
|
+
## Требования
|
|
182
|
+
|
|
183
|
+
- Apache Airflow
|
|
184
|
+
- Подключения к поддерживаемым БД, настроенные в Airflow
|
|
185
|
+
- Соответствующие драйверы БД (clickhouse-driver, psycopg2, etc.)
|
|
186
|
+
- Файлы SQL шаблонов для DDL и операций перемещения
|
|
187
|
+
|
|
188
|
+
## Примечания
|
|
189
|
+
|
|
190
|
+
- Класс использует временные таблицы для обеспечения целостности данных
|
|
191
|
+
- Все операции включают проверки качества данных, которые можно кастомизировать
|
|
192
|
+
- Поддерживаются различные методы сжатия для оптимизации передачи данных
|
|
193
|
+
- **В альфа-версии рекомендуется тщательно тестировать все сценарии использования**
|
|
194
|
+
|
|
195
|
+
## Сообщения об ошибках
|
|
196
|
+
|
|
197
|
+
При обнаружении ошибок или неожиданного поведения, пожалуйста, сообщайте о них для улучшения стабильности проекта
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
dbhose_airflow/__init__.py,sha256=yMh49tSwt9x66RNpZYJYBLw_fXMzwUzbycyzUyp3W1g,14352
|
|
2
|
+
dbhose_airflow/airflow_connect.py,sha256=unsRItnK4Q_ieMiGKEsCw8Q_8wkaXdVOfaSWLNRyujM,906
|
|
3
|
+
dbhose_airflow/dq_check.py,sha256=VoAw8qieA5LM1a7jaMPO3AQ7QXe_-ThZ8Gy868ozjHw,689
|
|
4
|
+
dbhose_airflow/dumper.py,sha256=9BEJ36yUJ9gH5PiVirLXymSKPOgABtp7Ee8U6MtEckY,1843
|
|
5
|
+
dbhose_airflow/move_method.py,sha256=c4g7wuiwDKudrKSWP4ov1atJGIFknHCgPnY9FMf9Ymc,477
|
|
6
|
+
dbhose_airflow-0.0.2.0.dist-info/licenses/CHANGELOG.md,sha256=7HHfS-x8gX3UXBOGEuPsgmlEOFWNRILjLlE3qrNaaqQ,532
|
|
7
|
+
dbhose_airflow-0.0.2.0.dist-info/licenses/README.md,sha256=-TsSFVS-bdRMNM-xhtqiZUXyD6D_lb6Uiz8LKEPGlP0,8822
|
|
8
|
+
dbhose_airflow-0.0.2.0.dist-info/METADATA,sha256=I0KTrMK0VYlrg9IMbjykKeo02GU-c1ZDxZKEjf4lLas,9434
|
|
9
|
+
dbhose_airflow-0.0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
10
|
+
dbhose_airflow-0.0.2.0.dist-info/top_level.txt,sha256=VlTXT0CLGGcVhbG9QPw2_a8H5UV03QMjvZ-NrPy6_jM,15
|
|
11
|
+
dbhose_airflow-0.0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Version History
|
|
2
|
+
|
|
3
|
+
## 0.0.2.0
|
|
4
|
+
|
|
5
|
+
* Update depends native-dumper==0.3.3.0
|
|
6
|
+
* Update depends pgpack-dumper==0.3.3.0
|
|
7
|
+
* Update README.md
|
|
8
|
+
* Add create partition into postgres and greenplum ddl queryes
|
|
9
|
+
* Improve delete.sql for greenplum and postgres
|
|
10
|
+
|
|
11
|
+
## 0.0.1.0
|
|
12
|
+
|
|
13
|
+
* Update depends native-dumper==0.3.2.3
|
|
14
|
+
* Update depends pgpack-dumper==0.3.2.2
|
|
15
|
+
* Move old README.md into OLD_DOCS.md
|
|
16
|
+
* Create new README.md
|
|
17
|
+
* Delete dbhose-utils from depends
|
|
18
|
+
* Rename repository dbhose -> dbhose_airflow
|
|
19
|
+
|
|
20
|
+
## 0.0.0.1
|
|
21
|
+
|
|
22
|
+
First version of the library dbhose_airflow
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# DBHose для Apache Airflow
|
|
2
|
+
|
|
3
|
+
```ascii
|
|
4
|
+
( )
|
|
5
|
+
( ( ) )\ ) ( ( /(
|
|
6
|
+
)\))( ' ( ( ) ( ( /( (()/( ( )\ )\()) (
|
|
7
|
+
((_)()\ ) ))\ )\ ( ( ( ))\ )\()) ( /(_)) )((_) ((_)\ ( ( ))\
|
|
8
|
+
_(())\_)() /((_) (( ) )\ )\ )\ ' /((_) (_))/ )\ (_))_ ((_)_ _((_) )\ )\ /((_)
|
|
9
|
+
\ \((_)/ /(_)) | | ((_) ((_) _((_)) (_)) | |_ ((_) | \ | _ ) | || | ((_) ((_) (_))
|
|
10
|
+
\ \/\/ / / -_) | | / _| / _ \ | ' \() / -_) | _| / _ \ | |) | | _ \ | __ | / _ \ (_-< / -_)
|
|
11
|
+
\_/\_/ \___| |_| \__| \___/ |_|_|_| \___| \__| \___/ |___/ |___/ |_||_| \___/ /__/ \___|
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Класс `DBHose` предоставляет универсальный интерфейс для переноса данных между различными источниками в Apache Airflow DAGs.
|
|
15
|
+
|
|
16
|
+
## ⚠️ Статус проекта
|
|
17
|
+
|
|
18
|
+
**Проект находится в стадии альфа-тестирования** и может содержать ошибки. Используйте с осторожностью в production-средах.
|
|
19
|
+
|
|
20
|
+
## Поддерживаемые СУБД
|
|
21
|
+
|
|
22
|
+
На данный момент работа с СУБД поддерживается только между следующими базами данных:
|
|
23
|
+
|
|
24
|
+
- **ClickHouse**
|
|
25
|
+
- **Greenplum**
|
|
26
|
+
- **PostgreSQL**
|
|
27
|
+
|
|
28
|
+
## Описание
|
|
29
|
+
|
|
30
|
+
DBHose - это инструмент для безопасного и эффективного перемещения данных между:
|
|
31
|
+
- Файлами дампов
|
|
32
|
+
- Python итераторами
|
|
33
|
+
- DataFrame (Pandas/Polars)
|
|
34
|
+
- Поддерживаемыми СУБД (ClickHouse, Greenplum, PostgreSQL)
|
|
35
|
+
|
|
36
|
+
Класс включает встроенные проверки качества данных (Data Quality) и поддерживает различные методы перемещения данных.
|
|
37
|
+
|
|
38
|
+
## Инициализация
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
DBHose(
|
|
42
|
+
table_dest: str,
|
|
43
|
+
connection_dest: str,
|
|
44
|
+
connection_src: str | None = None,
|
|
45
|
+
dq_skip_check: list[str] = [],
|
|
46
|
+
filter_by: list[str] = [],
|
|
47
|
+
drop_temp_table: bool = True,
|
|
48
|
+
move_method: MoveMethod = MoveMethod.replace,
|
|
49
|
+
custom_move: str | None = None,
|
|
50
|
+
compress_method: CompressionMethod = CompressionMethod.ZSTD,
|
|
51
|
+
timeout: int = DBMS_DEFAULT_TIMEOUT_SEC,
|
|
52
|
+
)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Параметры
|
|
56
|
+
|
|
57
|
+
- **`table_dest`** (`str`) - целевая таблица для загрузки данных
|
|
58
|
+
- **`connection_dest`** (`str`) - подключение к целевой БД (должна быть одной из поддерживаемых: ClickHouse, Greenplum, PostgreSQL)
|
|
59
|
+
- **`connection_src`** (`str`, optional) - подключение к исходной БД (если отличается от целевой)
|
|
60
|
+
- **`dq_skip_check`** (`list[str]`) - список проверок качества данных для пропуска
|
|
61
|
+
- **`filter_by`** (`list[str]`) - список колонок для фильтрации при перемещении данных
|
|
62
|
+
- **`drop_temp_table`** (`bool`) - удалять ли временную таблицу после операции (по умолчанию `True`)
|
|
63
|
+
- **`move_method`** (`MoveMethod`) - метод перемещения данных (по умолчанию `MoveMethod.replace`)
|
|
64
|
+
- **`custom_move`** (`str`, optional) - пользовательский SQL запрос для перемещения данных
|
|
65
|
+
- **`compress_method`** (`CompressionMethod`) - метод сжатия для дампов (по умолчанию `CompressionMethod.ZSTD`)
|
|
66
|
+
- **`timeout`** (`int`) - таймаут операций с БД в секундах (по умолчанию `DBMS_DEFAULT_TIMEOUT_SEC` = 300)
|
|
67
|
+
|
|
68
|
+
## Методы
|
|
69
|
+
|
|
70
|
+
### Основные методы загрузки данных
|
|
71
|
+
|
|
72
|
+
#### `from_file(fileobj: BufferedReader)`
|
|
73
|
+
Загрузка данных из файла дампа.
|
|
74
|
+
|
|
75
|
+
**Параметры:**
|
|
76
|
+
- `fileobj` (`BufferedReader`) - файловый объект для чтения дампа
|
|
77
|
+
|
|
78
|
+
#### `from_iterable(dtype_data: Iterable[Any])`
|
|
79
|
+
Загрузка данных из Python итератора.
|
|
80
|
+
|
|
81
|
+
**Параметры:**
|
|
82
|
+
- `dtype_data` (`Iterable[Any]`) - итерируемый объект с данными
|
|
83
|
+
|
|
84
|
+
#### `from_frame(data_frame: PDFrame | PLFrame)`
|
|
85
|
+
Загрузка данных из DataFrame (Pandas или Polars).
|
|
86
|
+
|
|
87
|
+
**Параметры:**
|
|
88
|
+
- `data_frame` (`PDFrame | PLFrame`) - DataFrame в формате Pandas или Polars
|
|
89
|
+
|
|
90
|
+
#### `from_dmbs(query: str | None = None, table: str | None = None)`
|
|
91
|
+
Загрузка данных из СУБД с использованием SQL запроса или прямой выгрузки из таблицы.
|
|
92
|
+
|
|
93
|
+
**Параметры:**
|
|
94
|
+
- `query` (`str`, optional) - SQL запрос для выборки данных
|
|
95
|
+
- `table` (`str`, optional) - имя таблицы для прямой выгрузки
|
|
96
|
+
|
|
97
|
+
### Вспомогательные методы
|
|
98
|
+
|
|
99
|
+
#### `create_temp()`
|
|
100
|
+
Создание временной таблицы для промежуточного хранения данных.
|
|
101
|
+
|
|
102
|
+
#### `drop_temp()`
|
|
103
|
+
Удаление временной таблицы.
|
|
104
|
+
|
|
105
|
+
#### `dq_check(table: str | None = None)`
|
|
106
|
+
Запуск проверок качества данных.
|
|
107
|
+
|
|
108
|
+
**Параметры:**
|
|
109
|
+
- `table` (`str`, optional) - имя исходной таблицы для сравнения данных
|
|
110
|
+
|
|
111
|
+
#### `to_table()`
|
|
112
|
+
Перемещение данных из временной таблицы в целевую.
|
|
113
|
+
|
|
114
|
+
## Пример использования в DAG
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from datetime import datetime
|
|
118
|
+
|
|
119
|
+
from airflow import DAG
|
|
120
|
+
from airflow.operators.python import PythonOperator
|
|
121
|
+
from dbhose_airflow import (
|
|
122
|
+
DBHose,
|
|
123
|
+
MoveMethod,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
def transfer_data():
|
|
127
|
+
# Перенос данных из PostgreSQL в ClickHouse
|
|
128
|
+
dbhose = DBHose(
|
|
129
|
+
table_dest="target_table",
|
|
130
|
+
connection_dest="clickhouse_conn",
|
|
131
|
+
connection_src="postgres_conn",
|
|
132
|
+
move_method=MoveMethod.replace
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
dbhose.from_dmbs(table="source_table")
|
|
136
|
+
|
|
137
|
+
with DAG('data_transfer_dag', start_date=datetime(2025, 10, 27)) as dag:
|
|
138
|
+
transfer_task = PythonOperator(
|
|
139
|
+
task_id='transfer_data',
|
|
140
|
+
python_callable=transfer_data
|
|
141
|
+
)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Ограничения альфа-версии
|
|
145
|
+
|
|
146
|
+
- Поддерживаются только ClickHouse, Greenplum и PostgreSQL
|
|
147
|
+
- Возможны ошибки при работе с большими объемами данных
|
|
148
|
+
- API может изменяться в будущих версиях
|
|
149
|
+
- Не все функции могут быть полностью протестированы
|
|
150
|
+
- Документация может быть неполной
|
|
151
|
+
|
|
152
|
+
## Особенности
|
|
153
|
+
|
|
154
|
+
- **Автоматическое создание временных таблиц** - данные сначала загружаются во временную таблицу
|
|
155
|
+
- **Проверки качества данных** - встроенные проверки перед финальным перемещением
|
|
156
|
+
- **Гибкие методы перемещения** - поддержка различных стратегий обновления данных
|
|
157
|
+
- **Поддержка множества источников** - файлы, DataFrame, СУБД
|
|
158
|
+
- **Логирование операций** - детальное логирование всех этапов процесса
|
|
159
|
+
|
|
160
|
+
## Требования
|
|
161
|
+
|
|
162
|
+
- Apache Airflow
|
|
163
|
+
- Подключения к поддерживаемым БД, настроенные в Airflow
|
|
164
|
+
- Соответствующие драйверы БД (clickhouse-driver, psycopg2, etc.)
|
|
165
|
+
- Файлы SQL шаблонов для DDL и операций перемещения
|
|
166
|
+
|
|
167
|
+
## Примечания
|
|
168
|
+
|
|
169
|
+
- Класс использует временные таблицы для обеспечения целостности данных
|
|
170
|
+
- Все операции включают проверки качества данных, которые можно кастомизировать
|
|
171
|
+
- Поддерживаются различные методы сжатия для оптимизации передачи данных
|
|
172
|
+
- **В альфа-версии рекомендуется тщательно тестировать все сценарии использования**
|
|
173
|
+
|
|
174
|
+
## Сообщения об ошибках
|
|
175
|
+
|
|
176
|
+
При обнаружении ошибок или неожиданного поведения, пожалуйста, сообщайте о них для улучшения стабильности проекта
|
|
@@ -1,432 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: dbhose_airflow
|
|
3
|
-
Version: 0.0.0.1
|
|
4
|
-
Summary: airflow class for exchanging data between DBMSs in native binary formats.
|
|
5
|
-
Home-page: https://github.com/0xMihalich/dbhose
|
|
6
|
-
Author: 0xMihalich
|
|
7
|
-
Author-email: bayanmobile87@gmail.com
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
License-File: README.md
|
|
10
|
-
License-File: CHANGELOG.md
|
|
11
|
-
Requires-Dist: apache-airflow>=2.4.3
|
|
12
|
-
Requires-Dist: dbhose-utils==0.0.0.6
|
|
13
|
-
Requires-Dist: native-dumper==0.3.2.2
|
|
14
|
-
Requires-Dist: pgpack-dumper==0.3.2.0
|
|
15
|
-
Dynamic: author
|
|
16
|
-
Dynamic: author-email
|
|
17
|
-
Dynamic: description
|
|
18
|
-
Dynamic: description-content-type
|
|
19
|
-
Dynamic: home-page
|
|
20
|
-
Dynamic: license-file
|
|
21
|
-
Dynamic: summary
|
|
22
|
-
|
|
23
|
-
# DBHose
|
|
24
|
-
|
|
25
|
-
Клиент для обмена данными между СУБД в нативных бинарных форматах
|
|
26
|
-
|
|
27
|
-
```ascii
|
|
28
|
-
( )
|
|
29
|
-
( ( ) )\ ) ( ( /(
|
|
30
|
-
)\))( ' ( ( ) ( ( /( (()/( ( )\ )\()) (
|
|
31
|
-
((_)()\ ) ))\ )\ ( ( ( ))\ )\()) ( /(_)) )((_) ((_)\ ( ( ))\
|
|
32
|
-
_(())\_)() /((_) (( ) )\ )\ )\ ' /((_) (_))/ )\ (_))_ ((_)_ _((_) )\ )\ /((_)
|
|
33
|
-
\ \((_)/ /(_)) | | ((_) ((_) _((_)) (_)) | |_ ((_) | \ | _ ) | || | ((_) ((_) (_))
|
|
34
|
-
\ \/\/ / / -_) | | / _| / _ \ | ' \() / -_) | _| / _ \ | |) | | _ \ | __ | / _ \ (_-< / -_)
|
|
35
|
-
\_/\_/ \___| |_| \__| \___/ |_|_|_| \___| \__| \___/ |___/ |___/ |_||_| \___/ /__/ \___|
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
## Аннотация
|
|
40
|
-
|
|
41
|
-
DBHose предназначен для обмена данными между различными СУБД с использованием их нативных бинарных форматов.
|
|
42
|
-
Решение позволяет избежать накладных расходов, связанных с промежуточными преобразованиями, обеспечивая производительность при переносе больших объемов данных.
|
|
43
|
-
На текущем этапе реализована поддержка PostgreSQL, Greenplum и ClickHouse, так же предусмотрена возможность расширения за счет подключения новых модулей.
|
|
44
|
-
|
|
45
|
-
## Архитектура и Ключевые Компоненты
|
|
46
|
-
|
|
47
|
-
Платформа построена по модульному принципу и состоит из нескольких взаимосвязанных библиотек, каждая из которых решает свою задачу.
|
|
48
|
-
|
|
49
|
-
## Низкоуровневые библиотеки для работы с бинарными форматами
|
|
50
|
-
|
|
51
|
-
### pgcopylib (PostgreSQL/Greenplum)
|
|
52
|
-
|
|
53
|
-
https://github.com/0xMihalich/pgcopylib
|
|
54
|
-
|
|
55
|
-
Назначение
|
|
56
|
-
|
|
57
|
-
* Парсинг и генерация бинарного формата COPY для PostgreSQL и совместимых СУБД.
|
|
58
|
-
|
|
59
|
-
Реализация
|
|
60
|
-
|
|
61
|
-
* Низкоуровневые функции на Cython для прямого доступа к структуре данных при сериализации и десериализации.
|
|
62
|
-
|
|
63
|
-
### pgpack (PostgreSQL/Greenplum) контейнер для хранения дампов pgcopy
|
|
64
|
-
|
|
65
|
-
https://github.com/0xMihalich/pgpack
|
|
66
|
-
|
|
67
|
-
Назначение
|
|
68
|
-
|
|
69
|
-
* Специализированный контейнер для локального хранения бинарных дампов.
|
|
70
|
-
|
|
71
|
-
Структура
|
|
72
|
-
|
|
73
|
-
* Заголовок b"PGPACK\n\x00" 8 байт
|
|
74
|
-
* Контрольная сумма метадаты zlib.crc32 4 байта
|
|
75
|
-
* Размер упакованного в zlib блока метадаты 4 байта
|
|
76
|
-
* Упакованный в zlib блок метадаты
|
|
77
|
-
* Метод компрессии 1 байт
|
|
78
|
-
* Размер упакованного блока pgcopy 8 байт
|
|
79
|
-
* Размер распакованного блока pgcopy 8 байт
|
|
80
|
-
* Упакованный блок pgcopy
|
|
81
|
-
|
|
82
|
-
Интерфейс
|
|
83
|
-
|
|
84
|
-
* PGPackReader для извлечения данных в виде списков Python объектов или pandas/polars DataFrame.
|
|
85
|
-
* PGPackWriter для записи данных из списков Python объектов или pandas/polars DataFrame.
|
|
86
|
-
|
|
87
|
-
### nativelib (ClickHouse)
|
|
88
|
-
|
|
89
|
-
https://github.com/0xMihalich/nativelib
|
|
90
|
-
|
|
91
|
-
Назначение
|
|
92
|
-
|
|
93
|
-
* Работа с нативным бинарным форматом ClickHouse.
|
|
94
|
-
|
|
95
|
-
Реализация
|
|
96
|
-
|
|
97
|
-
* Низкоуровневые функции на Cython.
|
|
98
|
-
Ключевое отличие от принципа работы clickhouse-driver — обход стандартного требования ClickHouse к использованию CityHash128 для каждого блока данных за счет использования HTTP-протокола, который позволяет применять сжатие ко всему потоку, что упрощает процесс и повышает скорость.
|
|
99
|
-
|
|
100
|
-
## light-compressor модуль для работы с компрессией в реальном времени (zstd, lz4)
|
|
101
|
-
|
|
102
|
-
https://github.com/0xMihalich/light_compressor
|
|
103
|
-
|
|
104
|
-
Назначение
|
|
105
|
-
|
|
106
|
-
* Оптимизированные компрессоры и декомпрессоры.
|
|
107
|
-
|
|
108
|
-
Реализация
|
|
109
|
-
|
|
110
|
-
* Переработанные низкоуровневые модули LZ4 и Zstandard с использованием Cython поверх CFFI и PyO3.
|
|
111
|
-
Оптимизировано для достижения максимально возможной скорости при взаимодействии с python для упаковки и распаковки.
|
|
112
|
-
|
|
113
|
-
## Драйверы для взаимодействия с СУБД
|
|
114
|
-
|
|
115
|
-
### pgpack_dumper (PostgreSQL/Greenplum)
|
|
116
|
-
|
|
117
|
-
https://github.com/0xMihalich/pgpack_dumper
|
|
118
|
-
|
|
119
|
-
Назначение
|
|
120
|
-
|
|
121
|
-
* Прием и отправка данных из таблиц, представлений, SQL запросов (поддерживается Multiquery), локальных файлов или представлений.
|
|
122
|
-
|
|
123
|
-
Реализация
|
|
124
|
-
|
|
125
|
-
* Использует psycopg с активацией бинарного режима COPY.
|
|
126
|
-
|
|
127
|
-
Принцип работы
|
|
128
|
-
|
|
129
|
-
Сохранение в файл формата PGPack
|
|
130
|
-
|
|
131
|
-
* получение метаданных -> получение pgcopy stream -> создание pgpack
|
|
132
|
-
|
|
133
|
-
```ascii
|
|
134
|
-
┌─────────────────────────────────────────────────┐
|
|
135
|
-
│ СОХРАНЕНИЕ В PGPACK │
|
|
136
|
-
└─────────────────────────────────────────────────┘
|
|
137
|
-
|
|
138
|
-
┌─────────────┐ 1. Метаданные ┌─────────────┐
|
|
139
|
-
│ │ ──────────────────► │ │
|
|
140
|
-
│ PostgreSQL │ │ PGPack │
|
|
141
|
-
│ │ 2. PGCopy Stream │ Container │
|
|
142
|
-
│ Table │ ──────────────────► │ │
|
|
143
|
-
│ │ │• Schema │
|
|
144
|
-
│ │ 3. Создание │• Data │
|
|
145
|
-
│ │ контейнера │• Compression│
|
|
146
|
-
└─────────────┘ └─────────────┘
|
|
147
|
-
│ │
|
|
148
|
-
│ psycopg binary COPY │ pgpack
|
|
149
|
-
▼ ▼
|
|
150
|
-
[Table Schema] → [Binary Stream] → [Zlib Schema] → [Compressed Data]
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
Запись из формата PGPack
|
|
154
|
-
|
|
155
|
-
* открытие PGPackReader -> получение pgcopy stream -> передача в целевую таблицу
|
|
156
|
-
|
|
157
|
-
```ascii
|
|
158
|
-
┌─────────────────────────────────────────────────┐
|
|
159
|
-
│ ЗАПИСЬ ИЗ PGPACK │
|
|
160
|
-
└─────────────────────────────────────────────────┘
|
|
161
|
-
|
|
162
|
-
┌─────────────┐ 1. Открытие ┌─────────────┐
|
|
163
|
-
│ │ ◄────────────────── │ │
|
|
164
|
-
│ PostgreSQL │ │ PGPack │
|
|
165
|
-
│ │ 2. PGCopy Stream │ Container │
|
|
166
|
-
│ Table │ ◄────────────────── │ │
|
|
167
|
-
│ │ │• Schema │
|
|
168
|
-
│ │ 3. Передача │• Data │
|
|
169
|
-
│ │ в таблицу │• Compression│
|
|
170
|
-
└─────────────┘ └─────────────┘
|
|
171
|
-
│ │
|
|
172
|
-
│ psycopg binary COPY │ pgpack
|
|
173
|
-
▼ ▼
|
|
174
|
-
[INSERT] ← [Binary Stream] ← [Zlib Decompress] ← [LZ4 Decompress]
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
Прямой обмен (PG/GP <-> PG/GP)
|
|
178
|
-
|
|
179
|
-
* Данные передаются без конвертации в режиме stream
|
|
180
|
-
|
|
181
|
-
```ascii
|
|
182
|
-
┌─────────────────────────────────────────────────┐
|
|
183
|
-
│ ПРЯМОЙ ОБМЕН PG/GP ↔ PG/GP │
|
|
184
|
-
└─────────────────────────────────────────────────┘
|
|
185
|
-
|
|
186
|
-
┌─────────────┐ ┌─────────────┐
|
|
187
|
-
│ Source │ │ Target │
|
|
188
|
-
│ PostgreSQL │ ─────────────────► │ PostgreSQL │
|
|
189
|
-
│ │ PGCopy Stream │ │
|
|
190
|
-
│ Table A │ (без конвертации)│ Table B │
|
|
191
|
-
│ │ ◄───────────────── │ │
|
|
192
|
-
└─────────────┘ └─────────────┘
|
|
193
|
-
│ │
|
|
194
|
-
│ │
|
|
195
|
-
▼ ▼
|
|
196
|
-
[Binary COPY] → [Network] → [Binary COPY]
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
Кросс-платформенная отправка (PG/GP -> ClickHouse)
|
|
200
|
-
|
|
201
|
-
* получение метаданных -> получение pgcopy stream -> преобразование в native stream -> передача в целевую таблицу
|
|
202
|
-
|
|
203
|
-
```ascii
|
|
204
|
-
┌─────────────────────────────────────────────────┐
|
|
205
|
-
│ PG/GP → ClickHouse (ОТПРАВКА) │
|
|
206
|
-
└─────────────────────────────────────────────────┘
|
|
207
|
-
|
|
208
|
-
┌─────────────┐ 1. Метаданные ┌─────────────┐
|
|
209
|
-
│ PostgreSQL │ ────┐ ┌───────── │ ClickHouse │
|
|
210
|
-
│ │ ▼ ▼ │ │
|
|
211
|
-
│ Table │ 2. PGCopy Stream │ Table │
|
|
212
|
-
│ │ ────┐ │ │
|
|
213
|
-
└─────────────┘ │ └─────────────┘
|
|
214
|
-
│ │ ▲
|
|
215
|
-
│ pgcopylib │ 4. Native Stream │ native_dumper
|
|
216
|
-
▼ │ │
|
|
217
|
-
[Binary COPY] → [Конвертер] → → [Native Format]
|
|
218
|
-
│
|
|
219
|
-
3. Преобразование
|
|
220
|
-
PGCopy → Native
|
|
221
|
-
│
|
|
222
|
-
nativelib + light_compressor
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
Кросс-платформенный прием (ClickHouse -> PG/GP)
|
|
226
|
-
|
|
227
|
-
* получение метаданных -> получение native stream -> преобразование в pgcopy stream -> передача в целевую таблицу
|
|
228
|
-
|
|
229
|
-
```ascii
|
|
230
|
-
┌─────────────────────────────────────────────────┐
|
|
231
|
-
│ ClickHouse → PG/GP (ПРИЕМ) │
|
|
232
|
-
└─────────────────────────────────────────────────┘
|
|
233
|
-
|
|
234
|
-
┌─────────────┐ 1. Метаданные ┌─────────────┐
|
|
235
|
-
│ ClickHouse │ ────┐ ┌───────── │ PostgreSQL │
|
|
236
|
-
│ │ ▼ ▼ │ │
|
|
237
|
-
│ Table │ 2. Native Stream │ Table │
|
|
238
|
-
│ │ ────┐ │ │
|
|
239
|
-
└─────────────┘ │ └─────────────┘
|
|
240
|
-
│ │ ▲
|
|
241
|
-
│ nativelib │ 4. PGCopy Stream │ pgpack_dumper
|
|
242
|
-
▼ │ │
|
|
243
|
-
[Native Format] → [Конвертер] → → [Binary COPY]
|
|
244
|
-
│
|
|
245
|
-
3. Преобразование
|
|
246
|
-
Native → PGCopy
|
|
247
|
-
│
|
|
248
|
-
pgcopylib + light_compressor
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### native_dumper (ClickHouse)
|
|
252
|
-
|
|
253
|
-
https://github.com/0xMihalich/native_dumper
|
|
254
|
-
|
|
255
|
-
Назначение
|
|
256
|
-
|
|
257
|
-
* Прием и отправка данных из таблиц, представлений, SQL запросов (поддерживается Multiquery), локальных файлов или представлений.
|
|
258
|
-
|
|
259
|
-
Реализация
|
|
260
|
-
|
|
261
|
-
* Кастомный HTTP-клиент, написанный на Rust, для работы с ClickHouse в формате Native.
|
|
262
|
-
Поддерживаемые типы сжатия LZ4, ZSTD или NONE (без компрессии).
|
|
263
|
-
|
|
264
|
-
Принцип работы
|
|
265
|
-
|
|
266
|
-
Сохранение в файл формата Native
|
|
267
|
-
|
|
268
|
-
* получение stream -> сохранение в файл
|
|
269
|
-
|
|
270
|
-
```ascii
|
|
271
|
-
┌─────────────────────────────────────────────────┐
|
|
272
|
-
│ СОХРАНЕНИЕ В NATIVE ФАЙЛ │
|
|
273
|
-
└─────────────────────────────────────────────────┘
|
|
274
|
-
|
|
275
|
-
┌─────────────┐ ┌─────────────┐
|
|
276
|
-
│ ClickHouse │ │ Native File │
|
|
277
|
-
│ │ │ │
|
|
278
|
-
│ Table │ ─────────────────► │ Format │
|
|
279
|
-
│ │ Native Stream │ │
|
|
280
|
-
│ │ │• Blocks │
|
|
281
|
-
│ │ │• Headers │
|
|
282
|
-
│ │ │• Compression│
|
|
283
|
-
└─────────────┘ └─────────────┘
|
|
284
|
-
│ │
|
|
285
|
-
│ native_dumper │ File.write()
|
|
286
|
-
▼ ▼
|
|
287
|
-
[Native Blocks] → → → → → → → → → [File]
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
Запись из формата Native
|
|
291
|
-
|
|
292
|
-
* определение кодека сжатия -> принятие решения менять компрессор или передавать как есть -> передача в целевую таблицу
|
|
293
|
-
|
|
294
|
-
```ascii
|
|
295
|
-
┌─────────────────────────────────────────────────┐
|
|
296
|
-
│ ЗАПИСЬ ИЗ NATIVE ФАЙЛА │
|
|
297
|
-
└─────────────────────────────────────────────────┘
|
|
298
|
-
|
|
299
|
-
┌─────────────┐ ┌─────────────┐
|
|
300
|
-
│ ClickHouse │ │ Native File │
|
|
301
|
-
│ │ │ │
|
|
302
|
-
│ Table │ ◄───────────────── │ Format │
|
|
303
|
-
│ │ Native Stream │ │
|
|
304
|
-
│ │ │• Blocks │
|
|
305
|
-
│ │ │• Headers │
|
|
306
|
-
│ │ │• Compression│
|
|
307
|
-
└─────────────┘ └─────────────┘
|
|
308
|
-
│ │
|
|
309
|
-
│ native_dumper │ File.read()
|
|
310
|
-
▼ ▼
|
|
311
|
-
[INSERT] ← [Native Blocks] ← [Decompression] ← [File Read]
|
|
312
|
-
│
|
|
313
|
-
Определение кодека сжатия
|
|
314
|
-
→ Решение: менять компрессор или оставить как есть
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
Прямой обмен (ClickHouse <-> ClickHouse)
|
|
318
|
-
|
|
319
|
-
* получение stream -> принятие решения менять компрессор или передавать как есть -> передача в целевую таблицу
|
|
320
|
-
|
|
321
|
-
```ascii
|
|
322
|
-
┌─────────────────────────────────────────────────┐
|
|
323
|
-
│ ПРЯМОЙ ОБМЕН CH ↔ ClickHouse │
|
|
324
|
-
└─────────────────────────────────────────────────┘
|
|
325
|
-
|
|
326
|
-
┌─────────────┐ ┌─────────────┐
|
|
327
|
-
│ Source │ │ Target │
|
|
328
|
-
│ ClickHouse │ ─────────────────► │ ClickHouse │
|
|
329
|
-
│ │ Native Stream │ │
|
|
330
|
-
│ Table A │ (минимальная │ Table B │
|
|
331
|
-
│ │ конвертация) │ │
|
|
332
|
-
│ │ ◄───────────────── │ │
|
|
333
|
-
└─────────────┘ └─────────────┘
|
|
334
|
-
│ │
|
|
335
|
-
│ native_dumper │ native_dumper
|
|
336
|
-
▼ ▼
|
|
337
|
-
[Native Format] → [Compression Decision] → [Native Format]
|
|
338
|
-
│
|
|
339
|
-
Анализ сжатия:
|
|
340
|
-
• Оставить исходный компрессор
|
|
341
|
-
• Или изменить на оптимальный
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
Кросс-платформенная отправка (ClickHouse -> PG/GP)
|
|
345
|
-
|
|
346
|
-
* получение метаданных PG/GP -> получение native stream -> преобразование в pgcopy stream -> передача в целевую таблицу
|
|
347
|
-
|
|
348
|
-
```ascii
|
|
349
|
-
┌─────────────────────────────────────────────────┐
|
|
350
|
-
│ ClickHouse → PG/GP (ОТПРАВКА) │
|
|
351
|
-
└─────────────────────────────────────────────────┘
|
|
352
|
-
|
|
353
|
-
┌─────────────┐ 1. Метаданные ┌─────────────┐
|
|
354
|
-
│ ClickHouse │ ┌───────────── │ PostgreSQL │
|
|
355
|
-
│ │ ▼ │ │
|
|
356
|
-
│ Table │ 2. Native Stream │ Table │
|
|
357
|
-
│ │ ────┐ │ │
|
|
358
|
-
└─────────────┘ │ └─────────────┘
|
|
359
|
-
│ │ ▲
|
|
360
|
-
│ nativelib │ 4. PGCopy Stream │ pgpack_dumper
|
|
361
|
-
▼ │ │
|
|
362
|
-
[Native Format] → [Конвертер] → → [Binary COPY]
|
|
363
|
-
│
|
|
364
|
-
3. Преобразование
|
|
365
|
-
Native → light_compressor → PGCopy
|
|
366
|
-
│
|
|
367
|
-
pgcopylib
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
Кросс-платформенный прием (PG/GP -> ClickHouse)
|
|
371
|
-
|
|
372
|
-
* получение метаданных Clickhouse -> получение pgcopy stream -> преобразование в native stream -> передача в целевую таблицу
|
|
373
|
-
|
|
374
|
-
```ascii
|
|
375
|
-
┌─────────────────────────────────────────────────┐
|
|
376
|
-
│ PG/GP → ClickHouse (ПРИЕМ) │
|
|
377
|
-
└─────────────────────────────────────────────────┘
|
|
378
|
-
|
|
379
|
-
┌─────────────┐ 1. Метаданные ┌─────────────┐
|
|
380
|
-
│ PostgreSQL │ ┌────────────── │ ClickHouse │
|
|
381
|
-
│ │ ▼ │ │
|
|
382
|
-
│ Table │ 2. PGCopy Stream │ Table │
|
|
383
|
-
│ │ ────┐ │ │
|
|
384
|
-
└─────────────┘ │ └─────────────┘
|
|
385
|
-
│ │ ▲
|
|
386
|
-
│ pgcopylib │ 4. Native Stream │ native_dumper
|
|
387
|
-
▼ │ │
|
|
388
|
-
[Binary COPY] → [Конвертер] → → [Native Format]
|
|
389
|
-
│
|
|
390
|
-
3. Преобразование
|
|
391
|
-
PGCopy → Native
|
|
392
|
-
│
|
|
393
|
-
nativelib + light_compressor
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
## DBHouse Utils
|
|
397
|
-
|
|
398
|
-
https://github.com/0xMihalich/dbhose_utils
|
|
399
|
-
|
|
400
|
-
Назначение
|
|
401
|
-
|
|
402
|
-
* Набор инструментов для конвертации между форматами Native, PGPack и PGCopy
|
|
403
|
-
|
|
404
|
-
Реализация
|
|
405
|
-
|
|
406
|
-
* Функция dump_detective для автоматического определения формата входного файла дампа и выбора соответствующего ридера
|
|
407
|
-
* Функция dump_convertor для конвертации дампа в другой формат либо смены кодека сжатия / распаковки в формат без компрессии
|
|
408
|
-
|
|
409
|
-
## Ключевые особенности
|
|
410
|
-
|
|
411
|
-
* Производительность: Использование нативных форматов и низкоуровневых оптимизаций на Cython/Rust минимизирует накладные расходы.
|
|
412
|
-
* Сжатие: Интеграция с алгоритмами LZ4 и ZSTD на уровне контейнера (pgpack) и сетевого протокола.
|
|
413
|
-
* Модульность: Архитектура позволяет добавлять поддержку других СУБД путем добавления новых библиотек.
|
|
414
|
-
* Использование: Каждая библиотека может быть использована как отдельный модуль, так же в разработке общий CLI-интерфейс.
|
|
415
|
-
|
|
416
|
-
## Дальнейшее развитие проекта
|
|
417
|
-
|
|
418
|
-
Ближайшее время
|
|
419
|
-
|
|
420
|
-
CLI с рабочим названием DBHose, который предоставит единую точку входа для управления всеми модулями и операциями по переносу данных.
|
|
421
|
-
|
|
422
|
-
Среднесрочная перспектива
|
|
423
|
-
|
|
424
|
-
* Багфикс того, что будет найдено в процессе тестирования
|
|
425
|
-
* Добавление поддержки других типов данных Clickhouse (nativelib)
|
|
426
|
-
* Добавление конвертации в формат parquiet
|
|
427
|
-
|
|
428
|
-
Долгосрочная перспектива
|
|
429
|
-
|
|
430
|
-
* Добавить модуль для работы с SQL Server (MS SQL)
|
|
431
|
-
* Добавить модуль для работы с MySQL
|
|
432
|
-
* Добавить модуль для работы с Oracle
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
dbhose_airflow/__init__.py,sha256=koEcB4BSaS7H2nvShUvtjA0lqE88pfgL3P3V0iZIRIw,14308
|
|
2
|
-
dbhose_airflow/airflow_connect.py,sha256=unsRItnK4Q_ieMiGKEsCw8Q_8wkaXdVOfaSWLNRyujM,906
|
|
3
|
-
dbhose_airflow/dq_check.py,sha256=VoAw8qieA5LM1a7jaMPO3AQ7QXe_-ThZ8Gy868ozjHw,689
|
|
4
|
-
dbhose_airflow/dumper.py,sha256=9BEJ36yUJ9gH5PiVirLXymSKPOgABtp7Ee8U6MtEckY,1843
|
|
5
|
-
dbhose_airflow/move_method.py,sha256=c4g7wuiwDKudrKSWP4ov1atJGIFknHCgPnY9FMf9Ymc,477
|
|
6
|
-
dbhose_airflow-0.0.0.1.dist-info/licenses/CHANGELOG.md,sha256=VSADpjzH2GZfjSM6ZZAficIrxpJlnvbwz2VzQwxXl3A,75
|
|
7
|
-
dbhose_airflow-0.0.0.1.dist-info/licenses/README.md,sha256=_HIKpo1Cs3G25Xa91Viajyjdxk_EPE6TKO9jnNFpWqA,24201
|
|
8
|
-
dbhose_airflow-0.0.0.1.dist-info/METADATA,sha256=VP91T5ddFaXOvMyuR_FuFU9x4TTpQkf55Zbz4yCVy5c,24842
|
|
9
|
-
dbhose_airflow-0.0.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
10
|
-
dbhose_airflow-0.0.0.1.dist-info/top_level.txt,sha256=VlTXT0CLGGcVhbG9QPw2_a8H5UV03QMjvZ-NrPy6_jM,15
|
|
11
|
-
dbhose_airflow-0.0.0.1.dist-info/RECORD,,
|
|
@@ -1,410 +0,0 @@
|
|
|
1
|
-
# DBHose
|
|
2
|
-
|
|
3
|
-
Клиент для обмена данными между СУБД в нативных бинарных форматах
|
|
4
|
-
|
|
5
|
-
```ascii
|
|
6
|
-
( )
|
|
7
|
-
( ( ) )\ ) ( ( /(
|
|
8
|
-
)\))( ' ( ( ) ( ( /( (()/( ( )\ )\()) (
|
|
9
|
-
((_)()\ ) ))\ )\ ( ( ( ))\ )\()) ( /(_)) )((_) ((_)\ ( ( ))\
|
|
10
|
-
_(())\_)() /((_) (( ) )\ )\ )\ ' /((_) (_))/ )\ (_))_ ((_)_ _((_) )\ )\ /((_)
|
|
11
|
-
\ \((_)/ /(_)) | | ((_) ((_) _((_)) (_)) | |_ ((_) | \ | _ ) | || | ((_) ((_) (_))
|
|
12
|
-
\ \/\/ / / -_) | | / _| / _ \ | ' \() / -_) | _| / _ \ | |) | | _ \ | __ | / _ \ (_-< / -_)
|
|
13
|
-
\_/\_/ \___| |_| \__| \___/ |_|_|_| \___| \__| \___/ |___/ |___/ |_||_| \___/ /__/ \___|
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
## Аннотация
|
|
18
|
-
|
|
19
|
-
DBHose предназначен для обмена данными между различными СУБД с использованием их нативных бинарных форматов.
|
|
20
|
-
Решение позволяет избежать накладных расходов, связанных с промежуточными преобразованиями, обеспечивая производительность при переносе больших объемов данных.
|
|
21
|
-
На текущем этапе реализована поддержка PostgreSQL, Greenplum и ClickHouse, так же предусмотрена возможность расширения за счет подключения новых модулей.
|
|
22
|
-
|
|
23
|
-
## Архитектура и Ключевые Компоненты
|
|
24
|
-
|
|
25
|
-
Платформа построена по модульному принципу и состоит из нескольких взаимосвязанных библиотек, каждая из которых решает свою задачу.
|
|
26
|
-
|
|
27
|
-
## Низкоуровневые библиотеки для работы с бинарными форматами
|
|
28
|
-
|
|
29
|
-
### pgcopylib (PostgreSQL/Greenplum)
|
|
30
|
-
|
|
31
|
-
https://github.com/0xMihalich/pgcopylib
|
|
32
|
-
|
|
33
|
-
Назначение
|
|
34
|
-
|
|
35
|
-
* Парсинг и генерация бинарного формата COPY для PostgreSQL и совместимых СУБД.
|
|
36
|
-
|
|
37
|
-
Реализация
|
|
38
|
-
|
|
39
|
-
* Низкоуровневые функции на Cython для прямого доступа к структуре данных при сериализации и десериализации.
|
|
40
|
-
|
|
41
|
-
### pgpack (PostgreSQL/Greenplum) контейнер для хранения дампов pgcopy
|
|
42
|
-
|
|
43
|
-
https://github.com/0xMihalich/pgpack
|
|
44
|
-
|
|
45
|
-
Назначение
|
|
46
|
-
|
|
47
|
-
* Специализированный контейнер для локального хранения бинарных дампов.
|
|
48
|
-
|
|
49
|
-
Структура
|
|
50
|
-
|
|
51
|
-
* Заголовок b"PGPACK\n\x00" 8 байт
|
|
52
|
-
* Контрольная сумма метадаты zlib.crc32 4 байта
|
|
53
|
-
* Размер упакованного в zlib блока метадаты 4 байта
|
|
54
|
-
* Упакованный в zlib блок метадаты
|
|
55
|
-
* Метод компрессии 1 байт
|
|
56
|
-
* Размер упакованного блока pgcopy 8 байт
|
|
57
|
-
* Размер распакованного блока pgcopy 8 байт
|
|
58
|
-
* Упакованный блок pgcopy
|
|
59
|
-
|
|
60
|
-
Интерфейс
|
|
61
|
-
|
|
62
|
-
* PGPackReader для извлечения данных в виде списков Python объектов или pandas/polars DataFrame.
|
|
63
|
-
* PGPackWriter для записи данных из списков Python объектов или pandas/polars DataFrame.
|
|
64
|
-
|
|
65
|
-
### nativelib (ClickHouse)
|
|
66
|
-
|
|
67
|
-
https://github.com/0xMihalich/nativelib
|
|
68
|
-
|
|
69
|
-
Назначение
|
|
70
|
-
|
|
71
|
-
* Работа с нативным бинарным форматом ClickHouse.
|
|
72
|
-
|
|
73
|
-
Реализация
|
|
74
|
-
|
|
75
|
-
* Низкоуровневые функции на Cython.
|
|
76
|
-
Ключевое отличие от принципа работы clickhouse-driver — обход стандартного требования ClickHouse к использованию CityHash128 для каждого блока данных за счет использования HTTP-протокола, который позволяет применять сжатие ко всему потоку, что упрощает процесс и повышает скорость.
|
|
77
|
-
|
|
78
|
-
## light-compressor модуль для работы с компрессией в реальном времени (zstd, lz4)
|
|
79
|
-
|
|
80
|
-
https://github.com/0xMihalich/light_compressor
|
|
81
|
-
|
|
82
|
-
Назначение
|
|
83
|
-
|
|
84
|
-
* Оптимизированные компрессоры и декомпрессоры.
|
|
85
|
-
|
|
86
|
-
Реализация
|
|
87
|
-
|
|
88
|
-
* Переработанные низкоуровневые модули LZ4 и Zstandard с использованием Cython поверх CFFI и PyO3.
|
|
89
|
-
Оптимизировано для достижения максимально возможной скорости при взаимодействии с python для упаковки и распаковки.
|
|
90
|
-
|
|
91
|
-
## Драйверы для взаимодействия с СУБД
|
|
92
|
-
|
|
93
|
-
### pgpack_dumper (PostgreSQL/Greenplum)
|
|
94
|
-
|
|
95
|
-
https://github.com/0xMihalich/pgpack_dumper
|
|
96
|
-
|
|
97
|
-
Назначение
|
|
98
|
-
|
|
99
|
-
* Прием и отправка данных из таблиц, представлений, SQL запросов (поддерживается Multiquery), локальных файлов или представлений.
|
|
100
|
-
|
|
101
|
-
Реализация
|
|
102
|
-
|
|
103
|
-
* Использует psycopg с активацией бинарного режима COPY.
|
|
104
|
-
|
|
105
|
-
Принцип работы
|
|
106
|
-
|
|
107
|
-
Сохранение в файл формата PGPack
|
|
108
|
-
|
|
109
|
-
* получение метаданных -> получение pgcopy stream -> создание pgpack
|
|
110
|
-
|
|
111
|
-
```ascii
|
|
112
|
-
┌─────────────────────────────────────────────────┐
|
|
113
|
-
│ СОХРАНЕНИЕ В PGPACK │
|
|
114
|
-
└─────────────────────────────────────────────────┘
|
|
115
|
-
|
|
116
|
-
┌─────────────┐ 1. Метаданные ┌─────────────┐
|
|
117
|
-
│ │ ──────────────────► │ │
|
|
118
|
-
│ PostgreSQL │ │ PGPack │
|
|
119
|
-
│ │ 2. PGCopy Stream │ Container │
|
|
120
|
-
│ Table │ ──────────────────► │ │
|
|
121
|
-
│ │ │• Schema │
|
|
122
|
-
│ │ 3. Создание │• Data │
|
|
123
|
-
│ │ контейнера │• Compression│
|
|
124
|
-
└─────────────┘ └─────────────┘
|
|
125
|
-
│ │
|
|
126
|
-
│ psycopg binary COPY │ pgpack
|
|
127
|
-
▼ ▼
|
|
128
|
-
[Table Schema] → [Binary Stream] → [Zlib Schema] → [Compressed Data]
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Запись из формата PGPack
|
|
132
|
-
|
|
133
|
-
* открытие PGPackReader -> получение pgcopy stream -> передача в целевую таблицу
|
|
134
|
-
|
|
135
|
-
```ascii
|
|
136
|
-
┌─────────────────────────────────────────────────┐
|
|
137
|
-
│ ЗАПИСЬ ИЗ PGPACK │
|
|
138
|
-
└─────────────────────────────────────────────────┘
|
|
139
|
-
|
|
140
|
-
┌─────────────┐ 1. Открытие ┌─────────────┐
|
|
141
|
-
│ │ ◄────────────────── │ │
|
|
142
|
-
│ PostgreSQL │ │ PGPack │
|
|
143
|
-
│ │ 2. PGCopy Stream │ Container │
|
|
144
|
-
│ Table │ ◄────────────────── │ │
|
|
145
|
-
│ │ │• Schema │
|
|
146
|
-
│ │ 3. Передача │• Data │
|
|
147
|
-
│ │ в таблицу │• Compression│
|
|
148
|
-
└─────────────┘ └─────────────┘
|
|
149
|
-
│ │
|
|
150
|
-
│ psycopg binary COPY │ pgpack
|
|
151
|
-
▼ ▼
|
|
152
|
-
[INSERT] ← [Binary Stream] ← [Zlib Decompress] ← [LZ4 Decompress]
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
Прямой обмен (PG/GP <-> PG/GP)
|
|
156
|
-
|
|
157
|
-
* Данные передаются без конвертации в режиме stream
|
|
158
|
-
|
|
159
|
-
```ascii
|
|
160
|
-
┌─────────────────────────────────────────────────┐
|
|
161
|
-
│ ПРЯМОЙ ОБМЕН PG/GP ↔ PG/GP │
|
|
162
|
-
└─────────────────────────────────────────────────┘
|
|
163
|
-
|
|
164
|
-
┌─────────────┐ ┌─────────────┐
|
|
165
|
-
│ Source │ │ Target │
|
|
166
|
-
│ PostgreSQL │ ─────────────────► │ PostgreSQL │
|
|
167
|
-
│ │ PGCopy Stream │ │
|
|
168
|
-
│ Table A │ (без конвертации)│ Table B │
|
|
169
|
-
│ │ ◄───────────────── │ │
|
|
170
|
-
└─────────────┘ └─────────────┘
|
|
171
|
-
│ │
|
|
172
|
-
│ │
|
|
173
|
-
▼ ▼
|
|
174
|
-
[Binary COPY] → [Network] → [Binary COPY]
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
Кросс-платформенная отправка (PG/GP -> ClickHouse)
|
|
178
|
-
|
|
179
|
-
* получение метаданных -> получение pgcopy stream -> преобразование в native stream -> передача в целевую таблицу
|
|
180
|
-
|
|
181
|
-
```ascii
|
|
182
|
-
┌─────────────────────────────────────────────────┐
|
|
183
|
-
│ PG/GP → ClickHouse (ОТПРАВКА) │
|
|
184
|
-
└─────────────────────────────────────────────────┘
|
|
185
|
-
|
|
186
|
-
┌─────────────┐ 1. Метаданные ┌─────────────┐
|
|
187
|
-
│ PostgreSQL │ ────┐ ┌───────── │ ClickHouse │
|
|
188
|
-
│ │ ▼ ▼ │ │
|
|
189
|
-
│ Table │ 2. PGCopy Stream │ Table │
|
|
190
|
-
│ │ ────┐ │ │
|
|
191
|
-
└─────────────┘ │ └─────────────┘
|
|
192
|
-
│ │ ▲
|
|
193
|
-
│ pgcopylib │ 4. Native Stream │ native_dumper
|
|
194
|
-
▼ │ │
|
|
195
|
-
[Binary COPY] → [Конвертер] → → [Native Format]
|
|
196
|
-
│
|
|
197
|
-
3. Преобразование
|
|
198
|
-
PGCopy → Native
|
|
199
|
-
│
|
|
200
|
-
nativelib + light_compressor
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Кросс-платформенный прием (ClickHouse -> PG/GP)
|
|
204
|
-
|
|
205
|
-
* получение метаданных -> получение native stream -> преобразование в pgcopy stream -> передача в целевую таблицу
|
|
206
|
-
|
|
207
|
-
```ascii
|
|
208
|
-
┌─────────────────────────────────────────────────┐
|
|
209
|
-
│ ClickHouse → PG/GP (ПРИЕМ) │
|
|
210
|
-
└─────────────────────────────────────────────────┘
|
|
211
|
-
|
|
212
|
-
┌─────────────┐ 1. Метаданные ┌─────────────┐
|
|
213
|
-
│ ClickHouse │ ────┐ ┌───────── │ PostgreSQL │
|
|
214
|
-
│ │ ▼ ▼ │ │
|
|
215
|
-
│ Table │ 2. Native Stream │ Table │
|
|
216
|
-
│ │ ────┐ │ │
|
|
217
|
-
└─────────────┘ │ └─────────────┘
|
|
218
|
-
│ │ ▲
|
|
219
|
-
│ nativelib │ 4. PGCopy Stream │ pgpack_dumper
|
|
220
|
-
▼ │ │
|
|
221
|
-
[Native Format] → [Конвертер] → → [Binary COPY]
|
|
222
|
-
│
|
|
223
|
-
3. Преобразование
|
|
224
|
-
Native → PGCopy
|
|
225
|
-
│
|
|
226
|
-
pgcopylib + light_compressor
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### native_dumper (ClickHouse)
|
|
230
|
-
|
|
231
|
-
https://github.com/0xMihalich/native_dumper
|
|
232
|
-
|
|
233
|
-
Назначение
|
|
234
|
-
|
|
235
|
-
* Прием и отправка данных из таблиц, представлений, SQL запросов (поддерживается Multiquery), локальных файлов или представлений.
|
|
236
|
-
|
|
237
|
-
Реализация
|
|
238
|
-
|
|
239
|
-
* Кастомный HTTP-клиент, написанный на Rust, для работы с ClickHouse в формате Native.
|
|
240
|
-
Поддерживаемые типы сжатия LZ4, ZSTD или NONE (без компрессии).
|
|
241
|
-
|
|
242
|
-
Принцип работы
|
|
243
|
-
|
|
244
|
-
Сохранение в файл формата Native
|
|
245
|
-
|
|
246
|
-
* получение stream -> сохранение в файл
|
|
247
|
-
|
|
248
|
-
```ascii
|
|
249
|
-
┌─────────────────────────────────────────────────┐
|
|
250
|
-
│ СОХРАНЕНИЕ В NATIVE ФАЙЛ │
|
|
251
|
-
└─────────────────────────────────────────────────┘
|
|
252
|
-
|
|
253
|
-
┌─────────────┐ ┌─────────────┐
|
|
254
|
-
│ ClickHouse │ │ Native File │
|
|
255
|
-
│ │ │ │
|
|
256
|
-
│ Table │ ─────────────────► │ Format │
|
|
257
|
-
│ │ Native Stream │ │
|
|
258
|
-
│ │ │• Blocks │
|
|
259
|
-
│ │ │• Headers │
|
|
260
|
-
│ │ │• Compression│
|
|
261
|
-
└─────────────┘ └─────────────┘
|
|
262
|
-
│ │
|
|
263
|
-
│ native_dumper │ File.write()
|
|
264
|
-
▼ ▼
|
|
265
|
-
[Native Blocks] → → → → → → → → → [File]
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
Запись из формата Native
|
|
269
|
-
|
|
270
|
-
* определение кодека сжатия -> принятие решения менять компрессор или передавать как есть -> передача в целевую таблицу
|
|
271
|
-
|
|
272
|
-
```ascii
|
|
273
|
-
┌─────────────────────────────────────────────────┐
|
|
274
|
-
│ ЗАПИСЬ ИЗ NATIVE ФАЙЛА │
|
|
275
|
-
└─────────────────────────────────────────────────┘
|
|
276
|
-
|
|
277
|
-
┌─────────────┐ ┌─────────────┐
|
|
278
|
-
│ ClickHouse │ │ Native File │
|
|
279
|
-
│ │ │ │
|
|
280
|
-
│ Table │ ◄───────────────── │ Format │
|
|
281
|
-
│ │ Native Stream │ │
|
|
282
|
-
│ │ │• Blocks │
|
|
283
|
-
│ │ │• Headers │
|
|
284
|
-
│ │ │• Compression│
|
|
285
|
-
└─────────────┘ └─────────────┘
|
|
286
|
-
│ │
|
|
287
|
-
│ native_dumper │ File.read()
|
|
288
|
-
▼ ▼
|
|
289
|
-
[INSERT] ← [Native Blocks] ← [Decompression] ← [File Read]
|
|
290
|
-
│
|
|
291
|
-
Определение кодека сжатия
|
|
292
|
-
→ Решение: менять компрессор или оставить как есть
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
Прямой обмен (ClickHouse <-> ClickHouse)
|
|
296
|
-
|
|
297
|
-
* получение stream -> принятие решения менять компрессор или передавать как есть -> передача в целевую таблицу
|
|
298
|
-
|
|
299
|
-
```ascii
|
|
300
|
-
┌─────────────────────────────────────────────────┐
|
|
301
|
-
│ ПРЯМОЙ ОБМЕН CH ↔ ClickHouse │
|
|
302
|
-
└─────────────────────────────────────────────────┘
|
|
303
|
-
|
|
304
|
-
┌─────────────┐ ┌─────────────┐
|
|
305
|
-
│ Source │ │ Target │
|
|
306
|
-
│ ClickHouse │ ─────────────────► │ ClickHouse │
|
|
307
|
-
│ │ Native Stream │ │
|
|
308
|
-
│ Table A │ (минимальная │ Table B │
|
|
309
|
-
│ │ конвертация) │ │
|
|
310
|
-
│ │ ◄───────────────── │ │
|
|
311
|
-
└─────────────┘ └─────────────┘
|
|
312
|
-
│ │
|
|
313
|
-
│ native_dumper │ native_dumper
|
|
314
|
-
▼ ▼
|
|
315
|
-
[Native Format] → [Compression Decision] → [Native Format]
|
|
316
|
-
│
|
|
317
|
-
Анализ сжатия:
|
|
318
|
-
• Оставить исходный компрессор
|
|
319
|
-
• Или изменить на оптимальный
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
Кросс-платформенная отправка (ClickHouse -> PG/GP)
|
|
323
|
-
|
|
324
|
-
* получение метаданных PG/GP -> получение native stream -> преобразование в pgcopy stream -> передача в целевую таблицу
|
|
325
|
-
|
|
326
|
-
```ascii
|
|
327
|
-
┌─────────────────────────────────────────────────┐
|
|
328
|
-
│ ClickHouse → PG/GP (ОТПРАВКА) │
|
|
329
|
-
└─────────────────────────────────────────────────┘
|
|
330
|
-
|
|
331
|
-
┌─────────────┐ 1. Метаданные ┌─────────────┐
|
|
332
|
-
│ ClickHouse │ ┌───────────── │ PostgreSQL │
|
|
333
|
-
│ │ ▼ │ │
|
|
334
|
-
│ Table │ 2. Native Stream │ Table │
|
|
335
|
-
│ │ ────┐ │ │
|
|
336
|
-
└─────────────┘ │ └─────────────┘
|
|
337
|
-
│ │ ▲
|
|
338
|
-
│ nativelib │ 4. PGCopy Stream │ pgpack_dumper
|
|
339
|
-
▼ │ │
|
|
340
|
-
[Native Format] → [Конвертер] → → [Binary COPY]
|
|
341
|
-
│
|
|
342
|
-
3. Преобразование
|
|
343
|
-
Native → light_compressor → PGCopy
|
|
344
|
-
│
|
|
345
|
-
pgcopylib
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
Кросс-платформенный прием (PG/GP -> ClickHouse)
|
|
349
|
-
|
|
350
|
-
* получение метаданных Clickhouse -> получение pgcopy stream -> преобразование в native stream -> передача в целевую таблицу
|
|
351
|
-
|
|
352
|
-
```ascii
|
|
353
|
-
┌─────────────────────────────────────────────────┐
|
|
354
|
-
│ PG/GP → ClickHouse (ПРИЕМ) │
|
|
355
|
-
└─────────────────────────────────────────────────┘
|
|
356
|
-
|
|
357
|
-
┌─────────────┐ 1. Метаданные ┌─────────────┐
|
|
358
|
-
│ PostgreSQL │ ┌────────────── │ ClickHouse │
|
|
359
|
-
│ │ ▼ │ │
|
|
360
|
-
│ Table │ 2. PGCopy Stream │ Table │
|
|
361
|
-
│ │ ────┐ │ │
|
|
362
|
-
└─────────────┘ │ └─────────────┘
|
|
363
|
-
│ │ ▲
|
|
364
|
-
│ pgcopylib │ 4. Native Stream │ native_dumper
|
|
365
|
-
▼ │ │
|
|
366
|
-
[Binary COPY] → [Конвертер] → → [Native Format]
|
|
367
|
-
│
|
|
368
|
-
3. Преобразование
|
|
369
|
-
PGCopy → Native
|
|
370
|
-
│
|
|
371
|
-
nativelib + light_compressor
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
## DBHouse Utils
|
|
375
|
-
|
|
376
|
-
https://github.com/0xMihalich/dbhose_utils
|
|
377
|
-
|
|
378
|
-
Назначение
|
|
379
|
-
|
|
380
|
-
* Набор инструментов для конвертации между форматами Native, PGPack и PGCopy
|
|
381
|
-
|
|
382
|
-
Реализация
|
|
383
|
-
|
|
384
|
-
* Функция dump_detective для автоматического определения формата входного файла дампа и выбора соответствующего ридера
|
|
385
|
-
* Функция dump_convertor для конвертации дампа в другой формат либо смены кодека сжатия / распаковки в формат без компрессии
|
|
386
|
-
|
|
387
|
-
## Ключевые особенности
|
|
388
|
-
|
|
389
|
-
* Производительность: Использование нативных форматов и низкоуровневых оптимизаций на Cython/Rust минимизирует накладные расходы.
|
|
390
|
-
* Сжатие: Интеграция с алгоритмами LZ4 и ZSTD на уровне контейнера (pgpack) и сетевого протокола.
|
|
391
|
-
* Модульность: Архитектура позволяет добавлять поддержку других СУБД путем добавления новых библиотек.
|
|
392
|
-
* Использование: Каждая библиотека может быть использована как отдельный модуль, так же в разработке общий CLI-интерфейс.
|
|
393
|
-
|
|
394
|
-
## Дальнейшее развитие проекта
|
|
395
|
-
|
|
396
|
-
Ближайшее время
|
|
397
|
-
|
|
398
|
-
CLI с рабочим названием DBHose, который предоставит единую точку входа для управления всеми модулями и операциями по переносу данных.
|
|
399
|
-
|
|
400
|
-
Среднесрочная перспектива
|
|
401
|
-
|
|
402
|
-
* Багфикс того, что будет найдено в процессе тестирования
|
|
403
|
-
* Добавление поддержки других типов данных Clickhouse (nativelib)
|
|
404
|
-
* Добавление конвертации в формат parquiet
|
|
405
|
-
|
|
406
|
-
Долгосрочная перспектива
|
|
407
|
-
|
|
408
|
-
* Добавить модуль для работы с SQL Server (MS SQL)
|
|
409
|
-
* Добавить модуль для работы с MySQL
|
|
410
|
-
* Добавить модуль для работы с Oracle
|
|
File without changes
|
|
File without changes
|