etlplus 0.4.6__py3-none-any.whl → 0.7.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.
- etlplus/cli/app.py +257 -129
- etlplus/cli/handlers.py +244 -135
- etlplus/cli/main.py +205 -50
- etlplus/config/pipeline.py +11 -0
- etlplus/database/__init__.py +42 -0
- etlplus/database/ddl.py +311 -0
- etlplus/database/engine.py +146 -0
- etlplus/database/orm.py +347 -0
- etlplus/database/schema.py +273 -0
- etlplus/run.py +2 -4
- etlplus/templates/__init__.py +5 -0
- etlplus/templates/ddl.sql.j2 +128 -0
- etlplus/templates/view.sql.j2 +69 -0
- {etlplus-0.4.6.dist-info → etlplus-0.7.0.dist-info}/METADATA +65 -1
- {etlplus-0.4.6.dist-info → etlplus-0.7.0.dist-info}/RECORD +19 -11
- {etlplus-0.4.6.dist-info → etlplus-0.7.0.dist-info}/WHEEL +0 -0
- {etlplus-0.4.6.dist-info → etlplus-0.7.0.dist-info}/entry_points.txt +0 -0
- {etlplus-0.4.6.dist-info → etlplus-0.7.0.dist-info}/licenses/LICENSE +0 -0
- {etlplus-0.4.6.dist-info → etlplus-0.7.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
{# ---------- helpers ---------- #}
|
|
2
|
+
{% macro qid(name) -%}[{{ name | replace(']', ']]') }}]{%- endmacro %}
|
|
3
|
+
{% macro qname(schema, name) -%}{{ qid(schema) }}.{{ qid(name) }}{%- endmacro %}
|
|
4
|
+
{% macro df_name(table, col) -%}DF_{{ table }}_{{ col }}{%- endmacro %}
|
|
5
|
+
{% macro ck_name(table, col) -%}CK_{{ table }}_{{ col }}{%- endmacro %}
|
|
6
|
+
|
|
7
|
+
{# ---------- create schema (optional) ---------- #}
|
|
8
|
+
{% if spec.create_schema | default(true) %}
|
|
9
|
+
IF
|
|
10
|
+
NOT EXISTS (
|
|
11
|
+
SELECT 1
|
|
12
|
+
FROM sys.schemas
|
|
13
|
+
WHERE name = N'{{ spec.schema }}'
|
|
14
|
+
)
|
|
15
|
+
EXEC ('CREATE SCHEMA {{ qid(spec.schema) }}');
|
|
16
|
+
GO
|
|
17
|
+
{% endif %}
|
|
18
|
+
|
|
19
|
+
{# ---------- create table guarded ---------- #}
|
|
20
|
+
{% set fqtn = qname(spec.schema, spec.table) %}
|
|
21
|
+
IF OBJECT_ID(N'{{ spec.schema }}.{{ spec.table }}', N'U') IS NULL
|
|
22
|
+
BEGIN
|
|
23
|
+
CREATE TABLE {{ fqtn }} (
|
|
24
|
+
{% set ns = namespace(maxlen=0) %}
|
|
25
|
+
{% for c in spec.columns %}
|
|
26
|
+
{% set nlen = (c.name|string)|length %}
|
|
27
|
+
{% if nlen > ns.maxlen %}{% set ns.maxlen = nlen %}{% endif %}
|
|
28
|
+
{% endfor %}
|
|
29
|
+
{% set indent_cols = ' ' %}
|
|
30
|
+
{% for c in spec.columns %}
|
|
31
|
+
{# Map-safe lookups so StrictUndefined never bites on missing keys #}
|
|
32
|
+
{%- set ctype = c.get('type') -%}
|
|
33
|
+
{%- set ident = c.get('identity') -%}
|
|
34
|
+
{%- set computed = c.get('computed') -%}
|
|
35
|
+
{%- set nullable = c.get('nullable', true) -%}
|
|
36
|
+
{%- set defv = c.get('default') -%}
|
|
37
|
+
{%- set checkv = c.get('check') -%}
|
|
38
|
+
{{- indent_cols -}}{{ qid(c.name) }} {{ ctype }}
|
|
39
|
+
{%- if computed %} AS ({{ computed }}) PERSISTED{%- endif -%}
|
|
40
|
+
{%- if nullable %} NULL{%- else %} NOT NULL{%- endif -%}
|
|
41
|
+
{%- if ident %} IDENTITY({{ ident.get('seed', 1) }}, {{ ident.get('increment', 1) }}){%- endif -%}
|
|
42
|
+
{%- if defv %} CONSTRAINT {{ qid(df_name(spec.table, c.name)) }} DEFAULT ({{ defv }}){%- endif -%}
|
|
43
|
+
{%- if checkv %} CONSTRAINT {{ qid(ck_name(spec.table, c.name)) }} CHECK ({{ checkv }}){%- endif -%}
|
|
44
|
+
{{ "," if not loop.last }}
|
|
45
|
+
{% endfor %}
|
|
46
|
+
|
|
47
|
+
{%- if spec.primary_key is defined and spec.primary_key %}
|
|
48
|
+
, CONSTRAINT {{ qid(spec.primary_key.name
|
|
49
|
+
| default('PK_' ~ spec.table)) }}
|
|
50
|
+
PRIMARY KEY CLUSTERED (
|
|
51
|
+
{%- for col in spec.primary_key.columns -%}
|
|
52
|
+
{{ qid(col) }}{{ ", " if not loop.last }}
|
|
53
|
+
{%- endfor -%}
|
|
54
|
+
)
|
|
55
|
+
{%- endif %}
|
|
56
|
+
|
|
57
|
+
{%- for uq in spec.unique_constraints | default([]) %}
|
|
58
|
+
, CONSTRAINT {{ qid(uq.name) }} UNIQUE (
|
|
59
|
+
{%- for col in uq.columns -%}
|
|
60
|
+
{{ qid(col) }}{{ ", " if not loop.last }}
|
|
61
|
+
{%- endfor -%}
|
|
62
|
+
)
|
|
63
|
+
{%- endfor %}
|
|
64
|
+
);
|
|
65
|
+
END
|
|
66
|
+
GO
|
|
67
|
+
|
|
68
|
+
{# ---------- indexes ---------- #}
|
|
69
|
+
{% for ix in spec.indexes | default([]) %}
|
|
70
|
+
{%- set ix_unique = ix.get('unique', false) -%}
|
|
71
|
+
{%- set ix_include = ix.get('include') -%}
|
|
72
|
+
{%- set ix_where = ix.get('where') -%}
|
|
73
|
+
IF
|
|
74
|
+
NOT EXISTS (
|
|
75
|
+
SELECT 1
|
|
76
|
+
FROM sys.indexes
|
|
77
|
+
WHERE name = N'{{ ix.name }}'
|
|
78
|
+
AND object_id = OBJECT_ID(N'{{ spec.schema }}.{{ spec.table }}')
|
|
79
|
+
)
|
|
80
|
+
BEGIN
|
|
81
|
+
CREATE{% if ix_unique %} UNIQUE{% endif %} INDEX {{ qid(ix.name) }}
|
|
82
|
+
ON {{ fqtn }} (
|
|
83
|
+
{%- for col in ix.columns -%}
|
|
84
|
+
{{ qid(col) }}{{ ", " if not loop.last }}
|
|
85
|
+
{%- endfor -%}
|
|
86
|
+
)
|
|
87
|
+
{%- if ix_include %}
|
|
88
|
+
INCLUDE (
|
|
89
|
+
{%- for col in ix_include -%}
|
|
90
|
+
{{ qid(col) }}{{ ", " if not loop.last }}
|
|
91
|
+
{%- endfor -%}
|
|
92
|
+
)
|
|
93
|
+
{%- endif -%}
|
|
94
|
+
{%- if ix_where %} WHERE {{ ix_where }}{% endif %};
|
|
95
|
+
END
|
|
96
|
+
GO
|
|
97
|
+
{% endfor %}
|
|
98
|
+
|
|
99
|
+
{# ---------- foreign keys ---------- #}
|
|
100
|
+
{% for fk in spec.foreign_keys | default([]) %}
|
|
101
|
+
IF
|
|
102
|
+
NOT EXISTS (
|
|
103
|
+
SELECT 1
|
|
104
|
+
FROM sys.foreign_keys
|
|
105
|
+
WHERE
|
|
106
|
+
name = N'{{ fk.name }}'
|
|
107
|
+
AND parent_object_id = OBJECT_ID(N'{{ spec.schema }}.{{ spec.table }}'
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
BEGIN
|
|
111
|
+
ALTER TABLE {{ fqtn }} WITH CHECK
|
|
112
|
+
ADD CONSTRAINT {{ qid(fk.name) }} FOREIGN KEY (
|
|
113
|
+
{%- for col in fk.columns -%}
|
|
114
|
+
{{ qid(col) }}{{ ", " if not loop.last }}
|
|
115
|
+
{%- endfor -%}
|
|
116
|
+
) REFERENCES
|
|
117
|
+
{{ qname(fk.ref_schema | default('dbo'), fk.ref_table) }} (
|
|
118
|
+
{%- for col in fk.ref_columns -%}
|
|
119
|
+
{{ qid(col) }}{{ ", " if not loop.last }}
|
|
120
|
+
{%- endfor -%}
|
|
121
|
+
)
|
|
122
|
+
{%- set on_upd = fk.get('on_update') -%}
|
|
123
|
+
{%- set on_del = fk.get('on_delete') -%}
|
|
124
|
+
{%- if on_upd %} ON UPDATE {{ on_upd }}{% endif -%}
|
|
125
|
+
{%- if on_del %} ON DELETE {{ on_del }}{% endif %};
|
|
126
|
+
END
|
|
127
|
+
GO
|
|
128
|
+
{% endfor %}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{# -- Helpers -- #}
|
|
2
|
+
{% macro qid(name) -%}
|
|
3
|
+
[{{ name | replace(']', ']]') }}]
|
|
4
|
+
{%- endmacro %}
|
|
5
|
+
|
|
6
|
+
{% macro qname(schema, name) -%}
|
|
7
|
+
{{ qid(schema) }}.{{ qid(name) }}
|
|
8
|
+
{%- endmacro %}
|
|
9
|
+
|
|
10
|
+
{# Convert any expression to nvarchar(MAX) with N'' for NULLs #}
|
|
11
|
+
{% macro to_str(expr) -%}
|
|
12
|
+
ISNULL(CONVERT(NVARCHAR(MAX), {{ expr }}), N'')
|
|
13
|
+
{%- endmacro %}
|
|
14
|
+
|
|
15
|
+
{# Normalize truthy values to 'TRUE' / 'FALSE' #}
|
|
16
|
+
{% macro truthy(expr) -%}
|
|
17
|
+
IIF(CONVERT(VARCHAR(5), {{ expr }}) IN ('TRUE', '1', 'YES'), 'TRUE', 'FALSE')
|
|
18
|
+
{%- endmacro %}
|
|
19
|
+
|
|
20
|
+
{# -- Create schema (optional) -- #}
|
|
21
|
+
{% if spec.create_schema | default(true) %}
|
|
22
|
+
IF
|
|
23
|
+
NOT EXISTS (
|
|
24
|
+
SELECT 1
|
|
25
|
+
FROM sys.schemas
|
|
26
|
+
WHERE name = N'{{ spec.schema }}'
|
|
27
|
+
)
|
|
28
|
+
EXEC ('CREATE SCHEMA {{ qid(spec.schema) }}');
|
|
29
|
+
GO
|
|
30
|
+
{% endif %}
|
|
31
|
+
|
|
32
|
+
{# -- SET options (match your source view) -- #}
|
|
33
|
+
SET QUOTED_IDENTIFIER ON
|
|
34
|
+
SET ANSI_NULLS ON
|
|
35
|
+
GO
|
|
36
|
+
|
|
37
|
+
{# -- Derive names with fallbacks so table-style specs also work -- #}
|
|
38
|
+
{% set view_name = spec.view if spec.view is defined else ('vw_' ~ spec.table) %}
|
|
39
|
+
{% set src_schema = (spec.from_schema if spec.from_schema is defined else (spec.schema if spec.schema is defined else 'dbo')) %}
|
|
40
|
+
{% set src_table = (
|
|
41
|
+
spec.from_table if spec.from_table is defined else
|
|
42
|
+
(spec.source_table if spec.source_table is defined else spec.table)
|
|
43
|
+
) %}
|
|
44
|
+
{% set indent_cols = ' ' %}
|
|
45
|
+
|
|
46
|
+
{# -- Create view -- #}
|
|
47
|
+
CREATE VIEW {{ qname(spec.schema | default('dbo'), view_name) }} AS
|
|
48
|
+
SELECT
|
|
49
|
+
{% if spec.projections is defined and spec.projections %}
|
|
50
|
+
{% for p in spec.projections %}
|
|
51
|
+
{%- if p.type is defined and (p.type | lower)[:8] == 'nvarchar' -%}
|
|
52
|
+
{{- indent_cols -}}{{ to_str(p.expr) }} AS {{ qid(p.alias) }}
|
|
53
|
+
{%- else -%}
|
|
54
|
+
{{- indent_cols -}}{{ p.expr }}
|
|
55
|
+
{%- endif -%}
|
|
56
|
+
{{ "," if not loop.last }}
|
|
57
|
+
{% endfor %}
|
|
58
|
+
{% else %}
|
|
59
|
+
{% for c in spec.columns | default([]) %}
|
|
60
|
+
{%- if c.type is defined and (c.type | lower)[:8] == 'nvarchar' -%}
|
|
61
|
+
{{- indent_cols -}}{{ to_str(qid(c.name)) }} AS {{ qid(c.name) }}
|
|
62
|
+
{%- else -%}
|
|
63
|
+
{{- indent_cols -}}{{ qid(c.name) }}
|
|
64
|
+
{%- endif -%}
|
|
65
|
+
{{ "," if not loop.last }}
|
|
66
|
+
{% endfor %}
|
|
67
|
+
{%- endif %}
|
|
68
|
+
FROM {{ qname(src_schema, src_table) }};
|
|
69
|
+
GO
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: etlplus
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: A Swiss Army knife for simple ETL operations
|
|
5
5
|
Home-page: https://github.com/Dagitali/ETLPlus
|
|
6
6
|
Author: ETLPlus Team
|
|
@@ -21,7 +21,10 @@ Requires-Dist: jinja2>=3.1.6
|
|
|
21
21
|
Requires-Dist: pyodbc>=5.3.0
|
|
22
22
|
Requires-Dist: python-dotenv>=1.2.1
|
|
23
23
|
Requires-Dist: pandas>=2.3.3
|
|
24
|
+
Requires-Dist: pydantic>=2.12.5
|
|
25
|
+
Requires-Dist: PyYAML>=6.0.3
|
|
24
26
|
Requires-Dist: requests>=2.32.5
|
|
27
|
+
Requires-Dist: SQLAlchemy>=2.0.45
|
|
25
28
|
Requires-Dist: typer>=0.21.0
|
|
26
29
|
Provides-Extra: dev
|
|
27
30
|
Requires-Dist: black>=25.9.0; extra == "dev"
|
|
@@ -61,6 +64,8 @@ package and command-line interface for data extraction, validation, transformati
|
|
|
61
64
|
- [Quickstart](#quickstart)
|
|
62
65
|
- [Usage](#usage)
|
|
63
66
|
- [Command Line Interface](#command-line-interface)
|
|
67
|
+
- [Inspect Pipelines](#inspect-pipelines)
|
|
68
|
+
- [Render SQL DDL](#render-sql-ddl)
|
|
64
69
|
- [Extract Data](#extract-data)
|
|
65
70
|
- [Validate Data](#validate-data)
|
|
66
71
|
- [Transform Data](#transform-data)
|
|
@@ -88,6 +93,14 @@ package and command-line interface for data extraction, validation, transformati
|
|
|
88
93
|
|
|
89
94
|
## Features
|
|
90
95
|
|
|
96
|
+
- **Check** data pipeline definitions before running them:
|
|
97
|
+
- Summarize jobs, sources, targets, and transforms
|
|
98
|
+
- Confirm configuration changes by printing focused sections on demand
|
|
99
|
+
|
|
100
|
+
- **Render** SQL DDL from shared table specs:
|
|
101
|
+
- Generate CREATE TABLE or view statements
|
|
102
|
+
- Swap templates or direct output to files for database migrations
|
|
103
|
+
|
|
91
104
|
- **Extract** data from multiple sources:
|
|
92
105
|
- Files (CSV, JSON, XML, YAML)
|
|
93
106
|
- Databases (connection string support)
|
|
@@ -169,6 +182,44 @@ etlplus --help
|
|
|
169
182
|
etlplus --version
|
|
170
183
|
```
|
|
171
184
|
|
|
185
|
+
#### Check Pipelines
|
|
186
|
+
|
|
187
|
+
Use `etlplus check` to explore pipeline YAML definitions without running them. The command can print
|
|
188
|
+
job names, summarize configured sources and targets, or drill into specific sections.
|
|
189
|
+
|
|
190
|
+
List jobs and show a pipeline summary:
|
|
191
|
+
```bash
|
|
192
|
+
etlplus check --config examples/configs/pipeline.yml --jobs
|
|
193
|
+
etlplus check --config examples/configs/pipeline.yml --summary
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Show sources or transforms for troubleshooting:
|
|
197
|
+
```bash
|
|
198
|
+
etlplus check --config examples/configs/pipeline.yml --sources
|
|
199
|
+
etlplus check --config examples/configs/pipeline.yml --transforms
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### Render SQL DDL
|
|
203
|
+
|
|
204
|
+
Use `etlplus render` to turn table schema specs into ready-to-run SQL. Render from a pipeline config
|
|
205
|
+
or from a standalone schema file, and choose the built-in `ddl` or `view` templates (or provide your
|
|
206
|
+
own).
|
|
207
|
+
|
|
208
|
+
Render all tables defined in a pipeline:
|
|
209
|
+
```bash
|
|
210
|
+
etlplus render --config examples/configs/pipeline.yml --template ddl
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Render a single table in that pipeline:
|
|
214
|
+
```bash
|
|
215
|
+
etlplus render --config examples/configs/pipeline.yml --table customers --template view
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Render from a standalone table spec to a file:
|
|
219
|
+
```bash
|
|
220
|
+
etlplus render --spec schemas/customer.yml --template view -o temp/customer_view.sql
|
|
221
|
+
```
|
|
222
|
+
|
|
172
223
|
#### Extract Data
|
|
173
224
|
|
|
174
225
|
Note: For file sources, the format is normally inferred from the filename extension. Use
|
|
@@ -306,6 +357,19 @@ For YAML-driven pipelines executed end-to-end (extract → validate → transfor
|
|
|
306
357
|
- Authoring: [`docs/pipeline-guide.md`](docs/pipeline-guide.md)
|
|
307
358
|
- Runner API and internals: [`docs/run-module.md`](docs/run-module.md)
|
|
308
359
|
|
|
360
|
+
CLI quick reference for pipelines:
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
# List jobs or show a pipeline summary
|
|
364
|
+
etlplus check --config examples/configs/pipeline.yml --jobs
|
|
365
|
+
etlplus check --config examples/configs/pipeline.yml --summary
|
|
366
|
+
|
|
367
|
+
# Run a job
|
|
368
|
+
etlplus run --config examples/configs/pipeline.yml --job file_to_file_customers
|
|
369
|
+
|
|
370
|
+
# Deprecated shim (will be removed): etlplus pipeline
|
|
371
|
+
```
|
|
372
|
+
|
|
309
373
|
### Complete ETL Pipeline Example
|
|
310
374
|
|
|
311
375
|
```bash
|
|
@@ -7,7 +7,7 @@ etlplus/file.py,sha256=RxIAsGDN4f_vNA2B5-ct88JNd_ISAyYbooIRE5DstS8,17972
|
|
|
7
7
|
etlplus/load.py,sha256=BwF3gT4gIr-5CvNMz_aLTCl-w2ihWSTxNVd4X92XFwI,8737
|
|
8
8
|
etlplus/mixins.py,sha256=ifGpHwWv7U00yqGf-kN93vJax2IiK4jaGtTsPsO3Oak,1350
|
|
9
9
|
etlplus/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
etlplus/run.py,sha256=
|
|
10
|
+
etlplus/run.py,sha256=X4kp5FQlIWVf1_d9oSrchKau7BFDCE1Zkscvu7WPaWw,12340
|
|
11
11
|
etlplus/run_helpers.py,sha256=bj6MkaeFxjl3CeKG1HoXKx5DwAlXNERVW-GX-z1P_qQ,24373
|
|
12
12
|
etlplus/transform.py,sha256=uAUVDDHYCgx7GpVez9IK3OAZM-CnCuMa9iox3vwGGJA,25296
|
|
13
13
|
etlplus/types.py,sha256=SJiZ7wJiSnV4CEvF-9E5nSFLBo4DT9OqHQqj1GSHkv8,6042
|
|
@@ -31,21 +31,29 @@ etlplus/api/rate_limiting/__init__.py,sha256=ZySB1dZettEDnWvI1EHf_TZ9L08M_kKsNR-
|
|
|
31
31
|
etlplus/api/rate_limiting/config.py,sha256=2b4wIynblN-1EyMqI4aXa71SljzSjXYh5N1Nngr3jOg,9406
|
|
32
32
|
etlplus/api/rate_limiting/rate_limiter.py,sha256=Uxozqd_Ej5Lsj-M-mLT2WexChgWh7x35_YP10yqYPQA,7159
|
|
33
33
|
etlplus/cli/__init__.py,sha256=J97-Rv931IL1_b4AXnB7Fbbd7HKnHBpx18NQfC_kE6c,299
|
|
34
|
-
etlplus/cli/app.py,sha256=
|
|
35
|
-
etlplus/cli/handlers.py,sha256=
|
|
36
|
-
etlplus/cli/main.py,sha256=
|
|
34
|
+
etlplus/cli/app.py,sha256=SYPO-NDwXgymJrACw39jZ_NJrSKAs0O8anuWR5o42WM,35893
|
|
35
|
+
etlplus/cli/handlers.py,sha256=nFMvqHQhJ8kJZPisDCiUHeOhjlqAO6hJvRjXiJTcU74,18951
|
|
36
|
+
etlplus/cli/main.py,sha256=ijYOy72SEsxrTEBan5yADW8CZyr0yddVF8HeMgFw6Zg,16576
|
|
37
37
|
etlplus/config/__init__.py,sha256=VZWzOg7d2YR9NT6UwKTv44yf2FRUMjTHynkm1Dl5Qzo,1486
|
|
38
38
|
etlplus/config/connector.py,sha256=0-TIwevHbKRHVmucvyGpPd-3tB1dKHB-dj0yJ6kq5eY,9809
|
|
39
39
|
etlplus/config/jobs.py,sha256=hmzRCqt0OvCEZZR4ONKrd3lvSv0OmayjLc4yOBk3ug8,7399
|
|
40
|
-
etlplus/config/pipeline.py,sha256=
|
|
40
|
+
etlplus/config/pipeline.py,sha256=Va4MQY6KEyKqHGMKPmh09ZcGpx95br-iNUjpkqtzVbw,9500
|
|
41
41
|
etlplus/config/profile.py,sha256=Ss2zedQGjkaGSpvBLTD4SZaWViMJ7TJPLB8Q2_BTpPg,1898
|
|
42
42
|
etlplus/config/types.py,sha256=a0epJ3z16HQ5bY3Ctf8s_cQPa3f0HHcwdOcjCP2xoG4,4954
|
|
43
43
|
etlplus/config/utils.py,sha256=4SUHMkt5bKBhMhiJm-DrnmE2Q4TfOgdNCKz8PJDS27o,3443
|
|
44
|
+
etlplus/database/__init__.py,sha256=0gWnMlQiVHS6SVUxIT9zklQUHU36y-2RF_gN1cx7icg,1018
|
|
45
|
+
etlplus/database/ddl.py,sha256=lIar9KIOoBRslp_P0DnpoMDXzkjt64J5-iVV7CeSV_M,7747
|
|
46
|
+
etlplus/database/engine.py,sha256=54f-XtNKIuogJhsLV9cX_xPoBwcl_HNJTL5HqMCi8kw,3986
|
|
47
|
+
etlplus/database/orm.py,sha256=StjeguokM70oNKq7mNXLyc4_mYUZR-EKW3oGRlsd8QE,9962
|
|
48
|
+
etlplus/database/schema.py,sha256=BmRP2wwX2xex1phLm0tnHrP6A2AQgguA-hSLnK0xwwc,7003
|
|
49
|
+
etlplus/templates/__init__.py,sha256=tsniN7XJYs3NwYxJ6c2HD5upHP3CDkLx-bQCMt97UOM,106
|
|
50
|
+
etlplus/templates/ddl.sql.j2,sha256=s8fMWvcb4eaJVXkifuib1aQPljtZ8buuyB_uA-ZdU3Q,4734
|
|
51
|
+
etlplus/templates/view.sql.j2,sha256=Iy8DHfhq5yyvrUKDxqp_aHIEXY4Tm6j4wT7YDEFWAhk,2180
|
|
44
52
|
etlplus/validation/__init__.py,sha256=Pe5Xg1_EA4uiNZGYu5WTF3j7odjmyxnAJ8rcioaplSQ,1254
|
|
45
53
|
etlplus/validation/utils.py,sha256=Mtqg449VIke0ziy_wd2r6yrwJzQkA1iulZC87FzXMjo,10201
|
|
46
|
-
etlplus-0.
|
|
47
|
-
etlplus-0.
|
|
48
|
-
etlplus-0.
|
|
49
|
-
etlplus-0.
|
|
50
|
-
etlplus-0.
|
|
51
|
-
etlplus-0.
|
|
54
|
+
etlplus-0.7.0.dist-info/licenses/LICENSE,sha256=MuNO63i6kWmgnV2pbP2SLqP54mk1BGmu7CmbtxMmT-U,1069
|
|
55
|
+
etlplus-0.7.0.dist-info/METADATA,sha256=ulMPDyXMX6p-NcxMBSZfegGrv0LNwAu_686_TVrkJPM,19383
|
|
56
|
+
etlplus-0.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
57
|
+
etlplus-0.7.0.dist-info/entry_points.txt,sha256=6w-2-jzuPa55spzK34h-UKh2JTEShh38adFRONNP9QE,45
|
|
58
|
+
etlplus-0.7.0.dist-info/top_level.txt,sha256=aWWF-udn_sLGuHTM6W6MLh99ArS9ROkUWO8Mi8y1_2U,8
|
|
59
|
+
etlplus-0.7.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|