etlplus 0.11.11__py3-none-any.whl → 0.12.2__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/file/yaml.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """
2
2
  :mod:`etlplus.file.yaml` module.
3
3
 
4
- Optional YAML read/write helpers.
4
+ Helpers for reading/writing YAML files.
5
5
  """
6
6
 
7
7
  from __future__ import annotations
@@ -15,6 +15,15 @@ from ..types import JSONDict
15
15
  from ..types import JSONList
16
16
  from ..utils import count_records
17
17
 
18
+ # SECTION: EXPORTS ========================================================== #
19
+
20
+
21
+ __all__ = [
22
+ 'read',
23
+ 'write',
24
+ ]
25
+
26
+
18
27
  # SECTION: INTERNAL CONSTANTS =============================================== #
19
28
 
20
29
 
@@ -59,7 +68,9 @@ def read(
59
68
  path: Path,
60
69
  ) -> JSONData:
61
70
  """
62
- Load and validate YAML payloads from ``path``.
71
+ Read YAML content from ``path``.
72
+
73
+ Validates that the YAML root is a dict or a list of dicts.
63
74
 
64
75
  Parameters
65
76
  ----------
etlplus/file/zip.py CHANGED
@@ -1,21 +1,95 @@
1
1
  """
2
2
  :mod:`etlplus.file.zip` module.
3
3
 
4
- Stub helpers for ZIP read/write.
4
+ Helpers for reading/writing ZIP files.
5
5
  """
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ import tempfile
10
+ import zipfile
9
11
  from pathlib import Path
10
12
 
11
13
  from ..types import JSONData
14
+ from ..types import JSONDict
15
+ from .enums import CompressionFormat
16
+ from .enums import FileFormat
17
+ from .enums import infer_file_format_and_compression
12
18
 
13
19
  # SECTION: EXPORTS ========================================================== #
14
20
 
15
21
 
16
- def read(path: Path) -> JSONData:
22
+ __all__ = [
23
+ 'read',
24
+ 'write',
25
+ ]
26
+
27
+
28
+ # SECTION: INTERNAL FUNCTIONS =============================================== #
29
+
30
+
31
+ def _resolve_format(
32
+ filename: str,
33
+ ) -> FileFormat:
34
+ """
35
+ Resolve the inner file format from a filename.
36
+
37
+ Parameters
38
+ ----------
39
+ filename : str
40
+ The name of the file inside the ZIP archive.
41
+
42
+ Returns
43
+ -------
44
+ FileFormat
45
+ The inferred inner file format.
46
+
47
+ Raises
48
+ ------
49
+ ValueError
50
+ If the file format cannot be inferred from the filename.
51
+ """
52
+ fmt, compression = infer_file_format_and_compression(filename)
53
+ if compression is not None and compression is not CompressionFormat.ZIP:
54
+ raise ValueError(f'Unexpected compression in archive: {filename}')
55
+ if fmt is None:
56
+ raise ValueError(
57
+ f'Cannot infer file format from compressed file {filename!r}',
58
+ )
59
+ return fmt
60
+
61
+
62
+ def _extract_payload(
63
+ entry: zipfile.ZipInfo,
64
+ archive: zipfile.ZipFile,
65
+ ) -> bytes:
66
+ """
67
+ Extract an archive entry into memory.
68
+
69
+ Parameters
70
+ ----------
71
+ entry : zipfile.ZipInfo
72
+ The ZIP archive entry.
73
+ archive : zipfile.ZipFile
74
+ The opened ZIP archive.
75
+
76
+ Returns
77
+ -------
78
+ bytes
79
+ The raw payload.
80
+ """
81
+ with archive.open(entry, 'r') as handle:
82
+ return handle.read()
83
+
84
+
85
+ # SECTION: FUNCTIONS ======================================================== #
86
+
87
+
88
+ def read(
89
+ path: Path,
90
+ ) -> JSONData:
17
91
  """
18
- Read ZIP content from ``path``.
92
+ Read ZIP content from ``path`` and parse the inner payload(s).
19
93
 
20
94
  Parameters
21
95
  ----------
@@ -26,13 +100,47 @@ def read(path: Path) -> JSONData:
26
100
  -------
27
101
  JSONData
28
102
  Parsed payload.
103
+
104
+ Raises
105
+ ------
106
+ ValueError
107
+ If the ZIP archive is empty.
29
108
  """
30
- raise NotImplementedError('ZIP read is not implemented yet')
109
+ with zipfile.ZipFile(path, 'r') as archive:
110
+ entries = [entry for entry in archive.infolist() if not entry.is_dir()]
111
+ if not entries:
112
+ raise ValueError(f'ZIP archive is empty: {path}')
113
+
114
+ if len(entries) == 1:
115
+ entry = entries[0]
116
+ fmt = _resolve_format(entry.filename)
117
+ payload = _extract_payload(entry, archive)
118
+ with tempfile.TemporaryDirectory() as tmpdir:
119
+ tmp_path = Path(tmpdir) / Path(entry.filename).name
120
+ tmp_path.write_bytes(payload)
121
+ from .core import File
122
+
123
+ return File(tmp_path, fmt).read()
124
+
125
+ results: JSONDict = {}
126
+ for entry in entries:
127
+ fmt = _resolve_format(entry.filename)
128
+ payload = _extract_payload(entry, archive)
129
+ with tempfile.TemporaryDirectory() as tmpdir:
130
+ tmp_path = Path(tmpdir) / Path(entry.filename).name
131
+ tmp_path.write_bytes(payload)
132
+ from .core import File
133
+
134
+ results[entry.filename] = File(tmp_path, fmt).read()
135
+ return results
31
136
 
32
137
 
33
- def write(path: Path, data: JSONData) -> int:
138
+ def write(
139
+ path: Path,
140
+ data: JSONData,
141
+ ) -> int:
34
142
  """
35
- Write ``data`` to ZIP at ``path``.
143
+ Write ``data`` to ZIP at ``path`` and return record count.
36
144
 
37
145
  Parameters
38
146
  ----------
@@ -46,4 +154,22 @@ def write(path: Path, data: JSONData) -> int:
46
154
  int
47
155
  Number of records written.
48
156
  """
49
- raise NotImplementedError('ZIP write is not implemented yet')
157
+ fmt = _resolve_format(path.name)
158
+ inner_name = Path(path.name).with_suffix('').name
159
+
160
+ with tempfile.TemporaryDirectory() as tmpdir:
161
+ tmp_path = Path(tmpdir) / inner_name
162
+ from .core import File
163
+
164
+ count = File(tmp_path, fmt).write(data)
165
+ payload = tmp_path.read_bytes()
166
+
167
+ path.parent.mkdir(parents=True, exist_ok=True)
168
+ with zipfile.ZipFile(
169
+ path,
170
+ 'w',
171
+ compression=zipfile.ZIP_DEFLATED,
172
+ ) as archive:
173
+ archive.writestr(inner_name, payload)
174
+
175
+ return count
@@ -0,0 +1,46 @@
1
+ # etlplus.templates subpackage
2
+
3
+ Documentation for the `etlplus.templates` subpackage: SQL and DDL template helpers.
4
+
5
+ - Provides Jinja2 templates for DDL and view generation
6
+ - Supports templated SQL for multiple database backends
7
+ - Includes helpers for rendering templates with schema metadata
8
+
9
+ Back to project overview: see the top-level [README](../../README.md).
10
+
11
+ - [etlplus.templates subpackage](#etlpustemplates-subpackage)
12
+ - [Available Templates](#available-templates)
13
+ - [Rendering Templates](#rendering-templates)
14
+ - [Example: Rendering a DDL Template](#example-rendering-a-ddl-template)
15
+ - [See Also](#see-also)
16
+
17
+ ## Available Templates
18
+
19
+ - `ddl.sql.j2`: Generic DDL (CREATE TABLE) template
20
+ - `view.sql.j2`: Generic view creation template
21
+
22
+ ## Rendering Templates
23
+
24
+ Use the helpers to render templates with your schema or table metadata:
25
+
26
+ ```python
27
+ from etlplus.templates import render_template
28
+
29
+ sql = render_template("ddl.sql.j2", schema=my_schema)
30
+ ```
31
+
32
+ ## Example: Rendering a DDL Template
33
+
34
+ ```python
35
+ from etlplus.templates import render_template
36
+
37
+ schema = {"name": "users", "columns": [ ... ]}
38
+ sql = render_template("ddl.sql.j2", schema=schema)
39
+ print(sql)
40
+ ```
41
+
42
+ ## See Also
43
+
44
+ - Top-level CLI and library usage in the main [README](../../README.md)
45
+ - DDL template in [ddl.sql.j2](ddl.sql.j2)
46
+ - View template in [view.sql.j2](view.sql.j2)
@@ -0,0 +1,50 @@
1
+ # etlplus.validation subpackage
2
+
3
+ Documentation for the `etlplus.validation` subpackage: data validation utilities and helpers.
4
+
5
+ - Provides flexible data validation for ETL pipelines
6
+ - Supports type checking, required fields, and custom rules
7
+ - Includes utilities for rule definition and validation logic
8
+
9
+ Back to project overview: see the top-level [README](../../README.md).
10
+
11
+ - [etlplus.validation subpackage](#etlplusvalidation-subpackage)
12
+ - [Validation Features](#validation-features)
13
+ - [Defining Validation Rules](#defining-validation-rules)
14
+ - [Example: Validating Data](#example-validating-data)
15
+ - [See Also](#see-also)
16
+
17
+ ## Validation Features
18
+
19
+ - Type checking (string, number, boolean, etc.)
20
+ - Required/optional fields
21
+ - Enum and pattern validation
22
+ - Custom rule support
23
+
24
+ ## Defining Validation Rules
25
+
26
+ Validation rules are defined as dictionaries specifying field types, requirements, and constraints:
27
+
28
+ ```python
29
+ rules = {
30
+ "name": {"type": "string", "required": True},
31
+ "age": {"type": "number", "min": 0, "max": 120},
32
+ }
33
+ ```
34
+
35
+ ## Example: Validating Data
36
+
37
+ ```python
38
+ from etlplus.validation import validate
39
+
40
+ result = validate({"name": "Alice", "age": 30}, rules)
41
+ if result["valid"]:
42
+ print("Data is valid!")
43
+ else:
44
+ print(result["errors"])
45
+ ```
46
+
47
+ ## See Also
48
+
49
+ - Top-level CLI and library usage in the main [README](../../README.md)
50
+ - Validation utilities in [utils.py](utils.py)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: etlplus
3
- Version: 0.11.11
3
+ Version: 0.12.2
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
@@ -17,8 +17,11 @@ Classifier: Programming Language :: Python :: 3.14
17
17
  Requires-Python: >=3.13,<3.15
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
+ Requires-Dist: fastavro>=1.12.1
20
21
  Requires-Dist: jinja2>=3.1.6
22
+ Requires-Dist: openpyxl>=3.1.5
21
23
  Requires-Dist: pyodbc>=5.3.0
24
+ Requires-Dist: pyarrow>=22.0.0
22
25
  Requires-Dist: python-dotenv>=1.2.1
23
26
  Requires-Dist: pandas>=2.3.3
24
27
  Requires-Dist: pydantic>=2.12.5
@@ -26,6 +29,8 @@ Requires-Dist: PyYAML>=6.0.3
26
29
  Requires-Dist: requests>=2.32.5
27
30
  Requires-Dist: SQLAlchemy>=2.0.45
28
31
  Requires-Dist: typer>=0.21.0
32
+ Requires-Dist: xlrd>=2.0.2
33
+ Requires-Dist: xlwt>=1.3.0
29
34
  Provides-Extra: dev
30
35
  Requires-Dist: black>=25.9.0; extra == "dev"
31
36
  Requires-Dist: build>=1.2.2; extra == "dev"
@@ -59,6 +64,7 @@ ETLPlus is a veritable Swiss Army knife for enabling simple ETL operations, offe
59
64
  package and command-line interface for data extraction, validation, transformation, and loading.
60
65
 
61
66
  - [ETLPlus](#etlplus)
67
+ - [Getting Started](#getting-started)
62
68
  - [Features](#features)
63
69
  - [Installation](#installation)
64
70
  - [Quickstart](#quickstart)
@@ -87,11 +93,27 @@ package and command-line interface for data extraction, validation, transformati
87
93
  - [Linting](#linting)
88
94
  - [Updating Demo Snippets](#updating-demo-snippets)
89
95
  - [Releasing to PyPI](#releasing-to-pypi)
90
- - [Links](#links)
91
96
  - [License](#license)
92
97
  - [Contributing](#contributing)
98
+ - [Documentation](#documentation)
99
+ - [Python Packages/Subpackage](#python-packagessubpackage)
100
+ - [Community Health](#community-health)
101
+ - [Other](#other)
93
102
  - [Acknowledgments](#acknowledgments)
94
103
 
104
+ ## Getting Started
105
+
106
+ ETLPlus helps you extract, validate, transform, and load data from files, databases, and APIs, either
107
+ as a Python library or from the command line.
108
+
109
+ To get started:
110
+
111
+ - See [Installation](#installation) for setup instructions.
112
+ - Try the [Quickstart](#quickstart) for a minimal working example (CLI and Python).
113
+ - Explore [Usage](#usage) for more detailed options and workflows.
114
+
115
+ ETLPlus supports Python 3.13 and above.
116
+
95
117
  ## Features
96
118
 
97
119
  - **Check** data pipeline definitions before running them:
@@ -416,7 +438,7 @@ etlplus transform \
416
438
  # 3. Validate transformed data
417
439
  etlplus validate \
418
440
  --rules '{"name": {"type": "string", "required": true}, "email": {"type": "string", "required": true}}' \
419
- temo/sample_transformed.json
441
+ temp/sample_transformed.json
420
442
 
421
443
  # 4. Load to CSV
422
444
  cat temp/sample_transformed.json \
@@ -603,17 +625,6 @@ git push origin v1.4.0
603
625
  If you want an extra smoke-test before tagging, run `make dist && pip install dist/*.whl` locally;
604
626
  this exercises the same build path the workflow uses.
605
627
 
606
- ## Links
607
-
608
- - API client docs: [`etlplus/api/README.md`](etlplus/api/README.md)
609
- - Examples: [`examples/README.md`](examples/README.md)
610
- - Pipeline authoring guide: [`docs/pipeline-guide.md`](docs/pipeline-guide.md)
611
- - Runner internals: [`docs/run-module.md`](docs/run-module.md)
612
- - Design notes (Mapping inputs, dict outputs): [`docs/pipeline-guide.md#design-notes-mapping-inputs-dict-outputs`](docs/pipeline-guide.md#design-notes-mapping-inputs-dict-outputs)
613
- - Typing philosophy: [`CONTRIBUTING.md#typing-philosophy`](CONTRIBUTING.md#typing-philosophy)
614
- - Demo and walkthrough: [`DEMO.md`](DEMO.md)
615
- - Additional references: [`REFERENCES.md`](`REFERENCES.md)
616
-
617
628
  ## License
618
629
 
619
630
  This project is licensed under the [MIT License](LICENSE).
@@ -637,6 +648,39 @@ If you choose to be a code contributor, please first refer these documents:
637
648
  - Typing philosophy (TypedDicts as editor hints, permissive runtime):
638
649
  [`CONTRIBUTING.md#typing-philosophy`](CONTRIBUTING.md#typing-philosophy)
639
650
 
651
+ ## Documentation
652
+
653
+ ### Python Packages/Subpackage
654
+
655
+ Navigate to detailed documentation for each subpackage:
656
+
657
+ - [etlplus.api](etlplus/api/README.md): Lightweight HTTP client and paginated REST helpers
658
+ - [etlplus.file](etlplus/file/README.md): Unified file format support and helpers
659
+ - [etlplus.config](etlplus/config/README.md): Configuration helpers for connectors, pipelines, jobs,
660
+ and profiles
661
+ - [etlplus.cli](etlplus/cli/README.md): Command-line interface for ETLPlus workflows
662
+ - [etlplus.database](etlplus/database/README.md): Database engine, schema, and ORM helpers
663
+ - [etlplus.templates](etlplus/templates/README.md): SQL and DDL template helpers
664
+ - [etlplus.validation](etlplus/validation/README.md): Data validation utilities and helpers
665
+
666
+ ### Community Health
667
+
668
+ - [Contributing Guidelines](CONTRIBUTING.md): How to contribute, report issues, and submit PRs
669
+ - [Code of Conduct](CODE_OF_CONDUCT.md): Community standards and expectations
670
+ - [Security Policy](SECURITY.md): Responsible disclosure and vulnerability reporting
671
+ - [Support](SUPPORT.md): Where to get help
672
+
673
+ ### Other
674
+
675
+ - API client docs: [`etlplus/api/README.md`](etlplus/api/README.md)
676
+ - Examples: [`examples/README.md`](examples/README.md)
677
+ - Pipeline authoring guide: [`docs/pipeline-guide.md`](docs/pipeline-guide.md)
678
+ - Runner internals: [`docs/run-module.md`](docs/run-module.md)
679
+ - Design notes (Mapping inputs, dict outputs): [`docs/pipeline-guide.md#design-notes-mapping-inputs-dict-outputs`](docs/pipeline-guide.md#design-notes-mapping-inputs-dict-outputs)
680
+ - Typing philosophy: [`CONTRIBUTING.md#typing-philosophy`](CONTRIBUTING.md#typing-philosophy)
681
+ - Demo and walkthrough: [`DEMO.md`](DEMO.md)
682
+ - Additional references: [`REFERENCES.md`](REFERENCES.md)
683
+
640
684
  ## Acknowledgments
641
685
 
642
686
  ETLPlus is inspired by common work patterns in data engineering and software engineering patterns in
@@ -1,3 +1,4 @@
1
+ etlplus/README.md,sha256=5jNes37UIy_THNmUr5HSAyS5mTCTa5tqRfEPnvsgV4s,1455
1
2
  etlplus/__init__.py,sha256=M2gScnyir6WOMAh_EuoQIiAzdcTls0_5hbd_Q6of8I0,1021
2
3
  etlplus/__main__.py,sha256=btoROneNiigyfBU7BSzPKZ1R9gzBMpxcpsbPwmuHwTM,479
3
4
  etlplus/__version__.py,sha256=1E0GMK_yUWCMQFKxXjTvyMwofi0qT2k4CDNiHWiymWE,327
@@ -12,7 +13,7 @@ etlplus/transform.py,sha256=uAUVDDHYCgx7GpVez9IK3OAZM-CnCuMa9iox3vwGGJA,25296
12
13
  etlplus/types.py,sha256=1hsDlnF6r76zAwaUYay-i6pCM-Y0IU5nP7Crj8PLCQ4,6157
13
14
  etlplus/utils.py,sha256=BMLTWAvCJj3zLEcffBgURYnu0UGhhXsfH2WWpAt7fV8,13363
14
15
  etlplus/validate.py,sha256=7rJoEI_SIILdPpoBqqh2UJqg9oeReDz34mYSlc3t7Qg,12989
15
- etlplus/api/README.md,sha256=ZiyjxLz0LfFCzeYKXwtH8yY1OJ4hXCju7t2ICroFoU8,7215
16
+ etlplus/api/README.md,sha256=aGTbcL-EqaiMTS7GToibmeTIzjX-viP2OtUDfIJnZEo,7913
16
17
  etlplus/api/__init__.py,sha256=P2JUYFy6Ep4t6xnsBiCBfQCkQLHYYhA-yXPXCobS8Y0,4295
17
18
  etlplus/api/auth.py,sha256=GOO5on-LoMS1GXTAhtK9rFcfpjbBcNeA6NE5UZwIq0g,12158
18
19
  etlplus/api/config.py,sha256=wRpOaZ31sPReVzEMme0jKl_37nqgraESwuYSNxP_xDo,17397
@@ -29,6 +30,7 @@ etlplus/api/pagination/paginator.py,sha256=wtdY_er4yfjx5yTUQJ1gPq-IuWmpLAHeG5buB
29
30
  etlplus/api/rate_limiting/__init__.py,sha256=ZySB1dZettEDnWvI1EHf_TZ9L08M_kKsNR-Y_lbU6kI,1070
30
31
  etlplus/api/rate_limiting/config.py,sha256=2b4wIynblN-1EyMqI4aXa71SljzSjXYh5N1Nngr3jOg,9406
31
32
  etlplus/api/rate_limiting/rate_limiter.py,sha256=Uxozqd_Ej5Lsj-M-mLT2WexChgWh7x35_YP10yqYPQA,7159
33
+ etlplus/cli/README.md,sha256=rl9VYNH5MluV0rh-eP7TbxJZ5BTMEIaksxhl_JXpYio,1233
32
34
  etlplus/cli/__init__.py,sha256=J97-Rv931IL1_b4AXnB7Fbbd7HKnHBpx18NQfC_kE6c,299
33
35
  etlplus/cli/commands.py,sha256=g8_m3A8HEMyTRu2HctNiRoi2gtB5oSZCUEcyq-PIXos,24669
34
36
  etlplus/cli/constants.py,sha256=E6Uy4WauLa_0zkzxqImXh-bb1gKdb9sBZQVc8QOzr2Q,1943
@@ -38,6 +40,7 @@ etlplus/cli/main.py,sha256=IgeqxypixfwLHR-QcpgVMQ7vMZ865bXOh2oO9v-BWeM,5234
38
40
  etlplus/cli/options.py,sha256=vfXT3YLh7wG1iC-aTdSg6ItMC8l6n0Lozmy53XjqLbA,1199
39
41
  etlplus/cli/state.py,sha256=Pfd8ru0wYIN7eGp1_A0tioqs1LiCDZCuJ6AnjZb6yYQ,8027
40
42
  etlplus/cli/types.py,sha256=tclhKVJXDqHzlTQBYKARfqMgDOcuBJ-Zej2pvFy96WM,652
43
+ etlplus/config/README.md,sha256=ot6oFZxTz4x83mj1_FrQ13dO0z2QkRFDnkCkx7NPsSs,1636
41
44
  etlplus/config/__init__.py,sha256=VZWzOg7d2YR9NT6UwKTv44yf2FRUMjTHynkm1Dl5Qzo,1486
42
45
  etlplus/config/connector.py,sha256=0-TIwevHbKRHVmucvyGpPd-3tB1dKHB-dj0yJ6kq5eY,9809
43
46
  etlplus/config/jobs.py,sha256=hmzRCqt0OvCEZZR4ONKrd3lvSv0OmayjLc4yOBk3ug8,7399
@@ -45,38 +48,42 @@ etlplus/config/pipeline.py,sha256=m4Jh0ctFcKrIx6zR7LEC0sYY5wq0o8NqOruWPlz6qmA,94
45
48
  etlplus/config/profile.py,sha256=Ss2zedQGjkaGSpvBLTD4SZaWViMJ7TJPLB8Q2_BTpPg,1898
46
49
  etlplus/config/types.py,sha256=a0epJ3z16HQ5bY3Ctf8s_cQPa3f0HHcwdOcjCP2xoG4,4954
47
50
  etlplus/config/utils.py,sha256=4SUHMkt5bKBhMhiJm-DrnmE2Q4TfOgdNCKz8PJDS27o,3443
51
+ etlplus/database/README.md,sha256=nUQVwLwGzmpA5_u4oYJYkPIhIuJAIdWsoeRgr4joAIE,1431
48
52
  etlplus/database/__init__.py,sha256=AKJsDl2RHuRGPS-eXgNJeh4aSncJP5Y0yLApBF6i7i8,1052
49
53
  etlplus/database/ddl.py,sha256=0dEM9SJMMabkhI_h-Fc0j9a1Sl5lSyZdI0bIeBVGm10,7913
50
54
  etlplus/database/engine.py,sha256=PUxXLvLPyc-KaxuW7fXe12wYci7EvUp-Ad1H3bGhUog,4058
51
55
  etlplus/database/orm.py,sha256=gCSqH-CjQz6tV9133-VqgiwokK5ylun0BwXaIWfImAo,10008
52
56
  etlplus/database/schema.py,sha256=813C0Dd3WE53KTYot4dgjAxctgKXLXx-8_Rk_4r2e28,7022
53
57
  etlplus/database/types.py,sha256=_pkQyC14TzAlgyeIqZG4F5LWYknZbHw3TW68Auk7Ya0,795
58
+ etlplus/file/README.md,sha256=avWnyeKfs3uP3qa-DVBJ6t05jS2oFUPeQ3xf1Ph0eC0,3626
54
59
  etlplus/file/__init__.py,sha256=X03bosSM-uSd6dh3ur0un6_ozFRw2Tm4PE6kVUjtXK8,475
55
- etlplus/file/avro.py,sha256=My9VCUSVmHrGVCr6AAWJmnjyXOzdYUGraL_Mvyvs3x4,1115
56
- etlplus/file/core.py,sha256=_8AgtXlw1SuderxA43C-SPjudvnzknlUdpAQynTPu28,8682
57
- etlplus/file/csv.py,sha256=VbMW_NaqCw03HlfvYzb9MoAgCXI3cl9qc4dASkTHoyw,1880
60
+ etlplus/file/avro.py,sha256=CsHJ8spxfGPgGwGsOLBS5_-sEvXAF23bTwEvFo46X9E,5007
61
+ etlplus/file/core.py,sha256=BkCliUez8SBEgpagxSeDbJixnX9QvD5XQp0dbYOOw0k,8692
62
+ etlplus/file/csv.py,sha256=ZH4M98F_Xm97YC5EYADmAMddshyh0gZFDOjiBmU9oC4,2007
58
63
  etlplus/file/enums.py,sha256=rwrbwj6PejG0c5v6jzcsmeNu9cSqDyWB1foIuM5UyJo,6648
59
- etlplus/file/feather.py,sha256=2YApt6tOFwyaNwekJ2kWFkmVzyyUPN_2TwE8_jf4ZCI,1145
60
- etlplus/file/gz.py,sha256=UaWzELOUHi8wuaK37ZbcsXqtV7ySfkiViKLqC5xqFpM,1095
61
- etlplus/file/json.py,sha256=xSV5PkZ_tZQuZNdLr1FQUwuCQXyL7Ch3WRJ3hkw0p68,1911
62
- etlplus/file/ndjson.py,sha256=XnqFngwjlekfuZiG-rjU0iJflStdCIFbRIS-HVbgmjs,1135
63
- etlplus/file/orc.py,sha256=fzXmHbfLibEypoltwU0a5t-Q6upQOc92b8tO_ftq0Kw,1105
64
- etlplus/file/parquet.py,sha256=gYTd1XSlizWDhZINTOJAt8z1XhVOiV3K86_a82nFs8w,1145
65
- etlplus/file/tsv.py,sha256=6VYowab5qNKNemuFPJbUzEgVz_pRrisSJCPWpQzMc4w,1105
66
- etlplus/file/txt.py,sha256=dkAHhZYi_fEcAm7irPKpg4l-ayXBrl7J1MWEigWvwRQ,1105
67
- etlplus/file/xls.py,sha256=56qP0Ug8IYeO1wvyL0nHI54BZa7IG8Nm7BB070wyEn0,1105
68
- etlplus/file/xlsx.py,sha256=SG4ILdxGXNdnwOakq4ExEDE6loWWrSEXFk47AZmwYzw,1115
69
- etlplus/file/xml.py,sha256=vjate5u9Z26LPlpvZsdzpqXsIUZRgen7oHa3ly-aIhs,3905
70
- etlplus/file/yaml.py,sha256=6KaWoG7oYB26EHX2TZ7LOgigO11Hoq3MH--adFq_Eck,3004
71
- etlplus/file/zip.py,sha256=IF6OznDqDHZNX1HmVUW3qHvNsy_7wRKGQ_iTHIBGG1U,912
64
+ etlplus/file/feather.py,sha256=zCjrnc34v6SdgZJv7AaKbrhl0rAIkmjRwiLIB-QIWlw,3426
65
+ etlplus/file/gz.py,sha256=NKsvIV7TIWn8USbvuZmRH9hr6OrXh4TzTfDykHD41Kk,2631
66
+ etlplus/file/json.py,sha256=_KAXb4rZ1C8xnaV10IkihuFh1lhbWvajFOlMrBCNVjQ,2099
67
+ etlplus/file/ndjson.py,sha256=gT-kgcqCUUSxtm2j-JMejoh65jk-njMvFwxKCquLZw0,2393
68
+ etlplus/file/orc.py,sha256=LRQocbfXqvAldegXXj2Q8jfNmqbZIZWaHMJOQtqx3vI,3356
69
+ etlplus/file/parquet.py,sha256=7oHwAxaNMRTXBXeVgn-h8yvkDnlT1g1SG_OmPdbM4Fo,3525
70
+ etlplus/file/tsv.py,sha256=WAZpyGCzjqVJpBURgB2QXbC8AKpJrEq7InDQitKFmh8,2039
71
+ etlplus/file/txt.py,sha256=BStC7crpkGT4qddEeAD1_1mi_2-vQSXLj2DI-ddPFQE,2206
72
+ etlplus/file/xls.py,sha256=9LyjIdoj-pRpro7x83ogT58BjKJerynZmBxWMndVX2s,3055
73
+ etlplus/file/xlsx.py,sha256=2xvEVY9i10xVm_6y_nxct8LXU7oYo_ShgTXbV2LGmdM,3397
74
+ etlplus/file/xml.py,sha256=rYtCPvyLn9djClN2xKeqRCPsMXnvCH4R8zj94NJRdQc,4018
75
+ etlplus/file/yaml.py,sha256=pWJf0rWyiRpOVOBAwVOosPsdIzuywZ_Cv8_tXLZ6RFw,3183
76
+ etlplus/file/zip.py,sha256=nd26V3S0edklriKnKOGDTLlO8RBXTda_zLLEQrJgKL4,4185
77
+ etlplus/templates/README.md,sha256=kHSZ8FWcrlrcWz0hBIbho-k1Bi-PL-DQ7g02o-g70c8,1355
72
78
  etlplus/templates/__init__.py,sha256=tsniN7XJYs3NwYxJ6c2HD5upHP3CDkLx-bQCMt97UOM,106
73
79
  etlplus/templates/ddl.sql.j2,sha256=s8fMWvcb4eaJVXkifuib1aQPljtZ8buuyB_uA-ZdU3Q,4734
74
80
  etlplus/templates/view.sql.j2,sha256=Iy8DHfhq5yyvrUKDxqp_aHIEXY4Tm6j4wT7YDEFWAhk,2180
81
+ etlplus/validation/README.md,sha256=qusyiyJu2DsaK80jlwfXVZ0iDgeuTPOX2EL3a_fcFiw,1401
75
82
  etlplus/validation/__init__.py,sha256=Pe5Xg1_EA4uiNZGYu5WTF3j7odjmyxnAJ8rcioaplSQ,1254
76
83
  etlplus/validation/utils.py,sha256=Mtqg449VIke0ziy_wd2r6yrwJzQkA1iulZC87FzXMjo,10201
77
- etlplus-0.11.11.dist-info/licenses/LICENSE,sha256=MuNO63i6kWmgnV2pbP2SLqP54mk1BGmu7CmbtxMmT-U,1069
78
- etlplus-0.11.11.dist-info/METADATA,sha256=tOSCfzl8_DwljNbSFXjrCB7hod5gyLOtPdGlsbm3XmA,21037
79
- etlplus-0.11.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
80
- etlplus-0.11.11.dist-info/entry_points.txt,sha256=6w-2-jzuPa55spzK34h-UKh2JTEShh38adFRONNP9QE,45
81
- etlplus-0.11.11.dist-info/top_level.txt,sha256=aWWF-udn_sLGuHTM6W6MLh99ArS9ROkUWO8Mi8y1_2U,8
82
- etlplus-0.11.11.dist-info/RECORD,,
84
+ etlplus-0.12.2.dist-info/licenses/LICENSE,sha256=MuNO63i6kWmgnV2pbP2SLqP54mk1BGmu7CmbtxMmT-U,1069
85
+ etlplus-0.12.2.dist-info/METADATA,sha256=y2wnRX4-3zOF5lWbXfsH3W6dmaaH0iQz9Dovws7wkEc,22878
86
+ etlplus-0.12.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
87
+ etlplus-0.12.2.dist-info/entry_points.txt,sha256=6w-2-jzuPa55spzK34h-UKh2JTEShh38adFRONNP9QE,45
88
+ etlplus-0.12.2.dist-info/top_level.txt,sha256=aWWF-udn_sLGuHTM6W6MLh99ArS9ROkUWO8Mi8y1_2U,8
89
+ etlplus-0.12.2.dist-info/RECORD,,