openingest 2.5.0__tar.gz
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.
- openingest-2.5.0/LICENSE +21 -0
- openingest-2.5.0/PKG-INFO +299 -0
- openingest-2.5.0/README.md +595 -0
- openingest-2.5.0/core/__init__.py +0 -0
- openingest-2.5.0/core/airflow/__init__.py +0 -0
- openingest-2.5.0/core/airflow/runner.py +132 -0
- openingest-2.5.0/core/airflow/task_factory.py +37 -0
- openingest-2.5.0/core/airflow_runner.py +55 -0
- openingest-2.5.0/core/connectors/__init__.py +10 -0
- openingest-2.5.0/core/connectors/api/__init__.py +1 -0
- openingest-2.5.0/core/connectors/api/rest_connector.py +338 -0
- openingest-2.5.0/core/connectors/base.py +52 -0
- openingest-2.5.0/core/connectors/cloud/__init__.py +1 -0
- openingest-2.5.0/core/connectors/cloud/azure_connector.py +185 -0
- openingest-2.5.0/core/connectors/cloud/gcs_connector.py +172 -0
- openingest-2.5.0/core/connectors/cloud/s3_connector.py +189 -0
- openingest-2.5.0/core/connectors/formats/__init__.py +1 -0
- openingest-2.5.0/core/connectors/formats/csv_connector.py +58 -0
- openingest-2.5.0/core/connectors/formats/excel_connector.py +106 -0
- openingest-2.5.0/core/connectors/formats/json_connector.py +145 -0
- openingest-2.5.0/core/connectors/formats/parquet_connector.py +92 -0
- openingest-2.5.0/core/connectors/registry.py +85 -0
- openingest-2.5.0/core/discovery.py +241 -0
- openingest-2.5.0/core/incremental.py +322 -0
- openingest-2.5.0/core/ingestion.py +227 -0
- openingest-2.5.0/core/lineage.py +234 -0
- openingest-2.5.0/core/metadata.py +12 -0
- openingest-2.5.0/core/notifications.py +229 -0
- openingest-2.5.0/core/observability.py +262 -0
- openingest-2.5.0/core/pipeline.py +126 -0
- openingest-2.5.0/core/quality.py +44 -0
- openingest-2.5.0/core/quality_report.py +32 -0
- openingest-2.5.0/core/quality_rules.py +301 -0
- openingest-2.5.0/core/reporting.py +82 -0
- openingest-2.5.0/core/scheduler.py +188 -0
- openingest-2.5.0/core/schema.py +276 -0
- openingest-2.5.0/core/validation.py +36 -0
- openingest-2.5.0/core/warehouse.py +5 -0
- openingest-2.5.0/docs/USABILITY_AND_OBSERVABILITY.md +243 -0
- openingest-2.5.0/models/__init__.py +0 -0
- openingest-2.5.0/models/dataset.py +49 -0
- openingest-2.5.0/models/pipeline_run.py +23 -0
- openingest-2.5.0/openingest/__init__.py +3 -0
- openingest-2.5.0/openingest/cli.py +5 -0
- openingest-2.5.0/openingest/templates/__init__.py +1 -0
- openingest-2.5.0/openingest/templates/project/.openingest +1 -0
- openingest-2.5.0/openingest/templates/project/README.md +29 -0
- openingest-2.5.0/openingest/templates/project/configs/datasets.yaml +19 -0
- openingest-2.5.0/openingest/templates/project/configs/pipeline.yaml +2 -0
- openingest-2.5.0/openingest/templates/project/configs/validation_rules.yaml +1 -0
- openingest-2.5.0/openingest/templates/project/configs/warehouse.yaml +2 -0
- openingest-2.5.0/openingest/templates/project/data/raw/.gitkeep +1 -0
- openingest-2.5.0/openingest/templates/project/docker-compose.yml +16 -0
- openingest-2.5.0/openingest/templates/project/plugins/.gitkeep +1 -0
- openingest-2.5.0/openingest/templates/project/reports/.gitkeep +1 -0
- openingest-2.5.0/openingest/templates/project/sql/.gitkeep +1 -0
- openingest-2.5.0/openingest.egg-info/PKG-INFO +299 -0
- openingest-2.5.0/openingest.egg-info/SOURCES.txt +97 -0
- openingest-2.5.0/openingest.egg-info/dependency_links.txt +1 -0
- openingest-2.5.0/openingest.egg-info/entry_points.txt +2 -0
- openingest-2.5.0/openingest.egg-info/requires.txt +56 -0
- openingest-2.5.0/openingest.egg-info/top_level.txt +5 -0
- openingest-2.5.0/pyproject.toml +113 -0
- openingest-2.5.0/scripts/__init__.py +0 -0
- openingest-2.5.0/scripts/commands/__init__.py +0 -0
- openingest-2.5.0/scripts/commands/add_dataset.py +102 -0
- openingest-2.5.0/scripts/commands/airflow_cmd.py +58 -0
- openingest-2.5.0/scripts/commands/discover.py +81 -0
- openingest-2.5.0/scripts/commands/docker_cmd.py +85 -0
- openingest-2.5.0/scripts/commands/doctor.py +108 -0
- openingest-2.5.0/scripts/commands/graph.py +59 -0
- openingest-2.5.0/scripts/commands/infer.py +110 -0
- openingest-2.5.0/scripts/commands/init.py +75 -0
- openingest-2.5.0/scripts/commands/profile.py +100 -0
- openingest-2.5.0/scripts/commands/schedule.py +65 -0
- openingest-2.5.0/scripts/commands/version.py +22 -0
- openingest-2.5.0/scripts/dashboard.py +149 -0
- openingest-2.5.0/scripts/data_quality_checks.py +69 -0
- openingest-2.5.0/scripts/ingest_customers.py +41 -0
- openingest-2.5.0/scripts/ingest_orders.py +40 -0
- openingest-2.5.0/scripts/ingest_products.py +36 -0
- openingest-2.5.0/scripts/load_warehouse.py +21 -0
- openingest-2.5.0/scripts/openingest.py +293 -0
- openingest-2.5.0/scripts/pipeline_history.py +34 -0
- openingest-2.5.0/scripts/report.py +5 -0
- openingest-2.5.0/scripts/run_pipeline.py +5 -0
- openingest-2.5.0/scripts/setup_database.py +40 -0
- openingest-2.5.0/scripts/transform_data.py +0 -0
- openingest-2.5.0/setup.cfg +4 -0
- openingest-2.5.0/tests/test_quality_report.py +46 -0
- openingest-2.5.0/tests/test_quality_rules.py +33 -0
- openingest-2.5.0/utils/__init__.py +0 -0
- openingest-2.5.0/utils/config.py +24 -0
- openingest-2.5.0/utils/config_loader.py +38 -0
- openingest-2.5.0/utils/db.py +11 -0
- openingest-2.5.0/utils/logger.py +0 -0
- openingest-2.5.0/utils/metadata_logger.py +195 -0
- openingest-2.5.0/utils/project.py +43 -0
- openingest-2.5.0/utils/schema_utils.py +15 -0
openingest-2.5.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Manish Kudtarkar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: openingest
|
|
3
|
+
Version: 2.5.0
|
|
4
|
+
Summary: Configuration-driven data ingestion framework with quality checks, metadata, and orchestration
|
|
5
|
+
Author: OpenIngest Contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: pandas
|
|
11
|
+
Requires-Dist: sqlalchemy
|
|
12
|
+
Requires-Dist: psycopg2-binary
|
|
13
|
+
Requires-Dist: python-dotenv
|
|
14
|
+
Requires-Dist: PyYAML==6.0.2
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
17
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
18
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
19
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
20
|
+
Provides-Extra: web
|
|
21
|
+
Requires-Dist: streamlit>=1.36; extra == "web"
|
|
22
|
+
Provides-Extra: excel
|
|
23
|
+
Requires-Dist: openpyxl>=3.1.2; extra == "excel"
|
|
24
|
+
Provides-Extra: parquet
|
|
25
|
+
Requires-Dist: pyarrow>=15.0; extra == "parquet"
|
|
26
|
+
Provides-Extra: s3
|
|
27
|
+
Requires-Dist: boto3>=1.34.0; extra == "s3"
|
|
28
|
+
Provides-Extra: azure
|
|
29
|
+
Requires-Dist: azure-storage-blob>=12.19.0; extra == "azure"
|
|
30
|
+
Provides-Extra: gcs
|
|
31
|
+
Requires-Dist: google-cloud-storage>=2.14.0; extra == "gcs"
|
|
32
|
+
Provides-Extra: api
|
|
33
|
+
Requires-Dist: requests>=2.31.0; extra == "api"
|
|
34
|
+
Provides-Extra: notifications
|
|
35
|
+
Requires-Dist: requests>=2.31.0; extra == "notifications"
|
|
36
|
+
Provides-Extra: v2
|
|
37
|
+
Requires-Dist: openpyxl>=3.1.2; extra == "v2"
|
|
38
|
+
Requires-Dist: pyarrow>=15.0; extra == "v2"
|
|
39
|
+
Requires-Dist: boto3>=1.34.0; extra == "v2"
|
|
40
|
+
Requires-Dist: azure-storage-blob>=12.19.0; extra == "v2"
|
|
41
|
+
Requires-Dist: google-cloud-storage>=2.14.0; extra == "v2"
|
|
42
|
+
Requires-Dist: requests>=2.31.0; extra == "v2"
|
|
43
|
+
Provides-Extra: all
|
|
44
|
+
Requires-Dist: openpyxl>=3.1.2; extra == "all"
|
|
45
|
+
Requires-Dist: pyarrow>=15.0; extra == "all"
|
|
46
|
+
Requires-Dist: boto3>=1.34.0; extra == "all"
|
|
47
|
+
Requires-Dist: azure-storage-blob>=12.19.0; extra == "all"
|
|
48
|
+
Requires-Dist: google-cloud-storage>=2.14.0; extra == "all"
|
|
49
|
+
Requires-Dist: requests>=2.31.0; extra == "all"
|
|
50
|
+
Requires-Dist: streamlit>=1.36; extra == "all"
|
|
51
|
+
Requires-Dist: pytest>=8.0; extra == "all"
|
|
52
|
+
Requires-Dist: pytest-cov>=5.0; extra == "all"
|
|
53
|
+
Requires-Dist: ruff>=0.4; extra == "all"
|
|
54
|
+
Requires-Dist: mypy>=1.10; extra == "all"
|
|
55
|
+
Dynamic: license-file
|
|
56
|
+
|
|
57
|
+
# OpenIngest — Usability and Observability
|
|
58
|
+
|
|
59
|
+
This document covers the monitoring, metadata, and notification capabilities of OpenIngest.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Metadata tables
|
|
64
|
+
|
|
65
|
+
Every pipeline execution writes to four PostgreSQL tables automatically created on first run.
|
|
66
|
+
|
|
67
|
+
### `pipeline_runs`
|
|
68
|
+
|
|
69
|
+
One row per full pipeline execution.
|
|
70
|
+
|
|
71
|
+
| Column | Type | Description |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| `run_id` | TEXT | Unique ID — format `OI-YYYYMMDD-XXXXXX` |
|
|
74
|
+
| `status` | TEXT | `SUCCESS` or `FAILED` |
|
|
75
|
+
| `total_datasets` | INTEGER | Datasets processed |
|
|
76
|
+
| `total_rows` | BIGINT | Total rows loaded |
|
|
77
|
+
| `total_duration` | FLOAT | Seconds |
|
|
78
|
+
| `started_at` | TIMESTAMP | Run start time |
|
|
79
|
+
| `finished_at` | TIMESTAMP | Run finish time |
|
|
80
|
+
|
|
81
|
+
### `pipeline_dataset_runs`
|
|
82
|
+
|
|
83
|
+
One row per dataset per execution.
|
|
84
|
+
|
|
85
|
+
| Column | Type | Description |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| `run_id` | TEXT | Foreign key to `pipeline_runs` |
|
|
88
|
+
| `dataset_name` | TEXT | Dataset name from `datasets.yaml` |
|
|
89
|
+
| `status` | TEXT | `SUCCESS` or `FAILED` |
|
|
90
|
+
| `rows_loaded` | BIGINT | Rows loaded this run |
|
|
91
|
+
| `duration_seconds` | FLOAT | Seconds |
|
|
92
|
+
| `target_table` | TEXT | Staging table name |
|
|
93
|
+
| `load_strategy` | TEXT | `replace`, `append`, or `incremental` |
|
|
94
|
+
| `load_mode` | TEXT | `FULL`, `APPEND`, or `INCREMENTAL` |
|
|
95
|
+
| `watermark_value` | TEXT | Latest watermark (incremental only) |
|
|
96
|
+
| `loaded_at` | TIMESTAMP | Completion timestamp |
|
|
97
|
+
|
|
98
|
+
### `pipeline_quality_runs`
|
|
99
|
+
|
|
100
|
+
One row per dataset per execution with quality metrics.
|
|
101
|
+
|
|
102
|
+
| Column | Type | Description |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `run_id` | TEXT | Foreign key to `pipeline_runs` |
|
|
105
|
+
| `dataset_name` | TEXT | Dataset name |
|
|
106
|
+
| `status` | TEXT | `PASS` or `FAIL` |
|
|
107
|
+
| `score` | FLOAT | Quality score 0.0–100.0 |
|
|
108
|
+
| `checks_total` | INTEGER | Total checks run |
|
|
109
|
+
| `checks_passed` | INTEGER | Checks that passed |
|
|
110
|
+
| `checks_failed` | INTEGER | Checks that failed |
|
|
111
|
+
|
|
112
|
+
### `pipeline_incremental_state`
|
|
113
|
+
|
|
114
|
+
Persists watermark state between runs for incremental datasets.
|
|
115
|
+
|
|
116
|
+
| Column | Type | Description |
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| `dataset_name` | TEXT | Primary key |
|
|
119
|
+
| `target_table` | TEXT | Staging table |
|
|
120
|
+
| `incremental_column` | TEXT | Watermark column name |
|
|
121
|
+
| `last_watermark_value` | TEXT | Last processed watermark |
|
|
122
|
+
| `last_rows_loaded` | BIGINT | Rows loaded on last run |
|
|
123
|
+
| `last_source_rows` | BIGINT | Total source rows on last run |
|
|
124
|
+
| `last_loaded_at` | TIMESTAMP | Timestamp of last successful run |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## CLI monitoring commands
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# Latest execution report — one-line summary per dataset
|
|
132
|
+
openingest report
|
|
133
|
+
|
|
134
|
+
# Full run history
|
|
135
|
+
openingest history
|
|
136
|
+
openingest history --limit 10
|
|
137
|
+
|
|
138
|
+
# Full monitoring dashboard — KPIs, dataset health, quality trends
|
|
139
|
+
openingest dashboard
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The dashboard shows:
|
|
143
|
+
- Pipeline KPIs (latest run status, total rows, quality score, duration)
|
|
144
|
+
- Dataset health snapshot (per-dataset rows, quality, watermark)
|
|
145
|
+
- Dataset-level trends across the last 20 runs
|
|
146
|
+
- Incremental loading statistics (new records, skipped, latest watermark)
|
|
147
|
+
- Quality distribution (PASS / FAIL counts)
|
|
148
|
+
- Slowest datasets by average duration
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Notifications (v2.5)
|
|
153
|
+
|
|
154
|
+
Configure in `configs/pipeline.yaml`:
|
|
155
|
+
|
|
156
|
+
```yaml
|
|
157
|
+
notifications:
|
|
158
|
+
slack:
|
|
159
|
+
webhook: ${SLACK_WEBHOOK_URL}
|
|
160
|
+
on: [success, failure] # which events trigger a notification
|
|
161
|
+
|
|
162
|
+
email:
|
|
163
|
+
smtp_host: smtp.gmail.com
|
|
164
|
+
smtp_port: 587
|
|
165
|
+
username: ${EMAIL_USERNAME}
|
|
166
|
+
password: ${EMAIL_PASSWORD}
|
|
167
|
+
from: openingest@company.com
|
|
168
|
+
to:
|
|
169
|
+
- data-team@company.com
|
|
170
|
+
- oncall@company.com
|
|
171
|
+
on: [failure] # only alert on failure
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Both channels support `on: [success]`, `on: [failure]`, or `on: [success, failure]` independently.
|
|
175
|
+
|
|
176
|
+
### Slack message format
|
|
177
|
+
|
|
178
|
+
Uses Slack Block Kit. Example success notification:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
✅ OpenIngest — Pipeline SUCCESS
|
|
182
|
+
|
|
183
|
+
Run ID : OI-20260703-3BB09C
|
|
184
|
+
Status : SUCCESS
|
|
185
|
+
Datasets : 8
|
|
186
|
+
Rows : 174,777
|
|
187
|
+
Duration : 4.21s
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Email format
|
|
191
|
+
|
|
192
|
+
Plain-text email via SMTP. Subject line:
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
✅ OpenIngest Pipeline: SUCCESS — OI-20260703-3BB09C
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Data lineage (v3.0)
|
|
201
|
+
|
|
202
|
+
The lineage engine builds a directed graph of how data flows through the pipeline per dataset.
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
from core.lineage import LineageGraph
|
|
206
|
+
|
|
207
|
+
graph = LineageGraph()
|
|
208
|
+
|
|
209
|
+
# Build lineage for all datasets after a run
|
|
210
|
+
for dataset in datasets:
|
|
211
|
+
graph.add_dataset_lineage(dataset)
|
|
212
|
+
|
|
213
|
+
# Terminal view
|
|
214
|
+
graph.print_ascii()
|
|
215
|
+
|
|
216
|
+
# Mermaid diagram (paste into any Mermaid renderer)
|
|
217
|
+
print(graph.to_mermaid())
|
|
218
|
+
|
|
219
|
+
# JSON for web UI or API
|
|
220
|
+
data = graph.to_dict()
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### ASCII output
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
customers
|
|
227
|
+
├─ customers.csv [source]
|
|
228
|
+
│
|
|
229
|
+
├─ Dataset Discovery
|
|
230
|
+
│
|
|
231
|
+
├─ Schema Validation [PASS]
|
|
232
|
+
│
|
|
233
|
+
├─ Quality Engine [PASS] 100.0%
|
|
234
|
+
│
|
|
235
|
+
├─ Ingest (replace) 174,777 rows
|
|
236
|
+
│
|
|
237
|
+
└─ stg_customers [staging]
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Mermaid output
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
flowchart TD
|
|
244
|
+
customers_source[("customers.csv")]
|
|
245
|
+
customers_discovery[["Dataset Discovery"]]
|
|
246
|
+
customers_schema_validation[["Schema Validation"]]
|
|
247
|
+
customers_quality_check{{"Quality Engine"}}
|
|
248
|
+
customers_ingest[["Ingest (replace)"]]
|
|
249
|
+
customers_staging[("stg_customers")]
|
|
250
|
+
|
|
251
|
+
customers_source --> customers_discovery
|
|
252
|
+
customers_discovery --> customers_schema_validation
|
|
253
|
+
customers_schema_validation --> customers_quality_check
|
|
254
|
+
customers_quality_check --> customers_ingest
|
|
255
|
+
customers_ingest --> customers_staging
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Observability queries
|
|
261
|
+
|
|
262
|
+
Direct SQL examples against the metadata tables:
|
|
263
|
+
|
|
264
|
+
```sql
|
|
265
|
+
-- Latest run summary
|
|
266
|
+
SELECT run_id, status, total_datasets, total_rows, total_duration, started_at
|
|
267
|
+
FROM pipeline_runs
|
|
268
|
+
ORDER BY started_at DESC
|
|
269
|
+
LIMIT 1;
|
|
270
|
+
|
|
271
|
+
-- Quality score trend for orders
|
|
272
|
+
SELECT r.started_at, q.score, q.status
|
|
273
|
+
FROM pipeline_quality_runs q
|
|
274
|
+
JOIN pipeline_runs r USING (run_id)
|
|
275
|
+
WHERE q.dataset_name = 'orders'
|
|
276
|
+
ORDER BY r.started_at DESC
|
|
277
|
+
LIMIT 30;
|
|
278
|
+
|
|
279
|
+
-- Rows loaded per dataset on the latest run
|
|
280
|
+
WITH latest AS (SELECT run_id FROM pipeline_runs ORDER BY started_at DESC LIMIT 1)
|
|
281
|
+
SELECT dataset_name, rows_loaded, load_strategy, load_mode, watermark_value
|
|
282
|
+
FROM pipeline_dataset_runs
|
|
283
|
+
WHERE run_id = (SELECT run_id FROM latest)
|
|
284
|
+
ORDER BY dataset_name;
|
|
285
|
+
|
|
286
|
+
-- Datasets that failed quality checks in the last 7 days
|
|
287
|
+
SELECT r.started_at, q.dataset_name, q.score, q.checks_failed
|
|
288
|
+
FROM pipeline_quality_runs q
|
|
289
|
+
JOIN pipeline_runs r USING (run_id)
|
|
290
|
+
WHERE q.status = 'FAIL'
|
|
291
|
+
AND r.started_at >= NOW() - INTERVAL '7 days'
|
|
292
|
+
ORDER BY r.started_at DESC;
|
|
293
|
+
|
|
294
|
+
-- Current watermark state for incremental datasets
|
|
295
|
+
SELECT dataset_name, incremental_column, last_watermark_value,
|
|
296
|
+
last_rows_loaded, last_loaded_at
|
|
297
|
+
FROM pipeline_incremental_state
|
|
298
|
+
ORDER BY dataset_name;
|
|
299
|
+
```
|