csv-to-db-py 0.1.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.
- csv_to_db_py-0.1.0/.github/workflows/publish.yaml +19 -0
- csv_to_db_py-0.1.0/.github/workflows/workflow.yaml +43 -0
- csv_to_db_py-0.1.0/.gitignore +25 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/.gitignore +1 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/final-review-fix-report.md +91 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/plan-path +1 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/progress.md +70 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-02798e6..bd3e9d5.diff +671 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-11102ec..f08c415.diff +501 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-27c87bb..11102ec.diff +144 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-49aa2f3..ff80dc8.diff +185 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-55479cd..27c87bb.diff +156 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-7ffe98c..f7751b0.diff +149 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-7ffe98c..fc851e2.diff +2058 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-8593195..49aa2f3.diff +90 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-ab9ee61..55479cd.diff +208 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-bd3e9d5..ab9ee61.diff +150 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-dbb469e..fc851e2.diff +136 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-f08c415..8593195.diff +27 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-f7751b0..02798e6.diff +129 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-fc851e2..9ee3e7a.diff +433 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/review-ff80dc8..dbb469e.diff +14 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-1-brief.md +12 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-1-report.md +53 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-10-brief.md +12 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-10-report.md +46 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-11-brief.md +15 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-11-report.md +35 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-12-brief.md +8 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-12-report.md +26 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-13-brief.md +7 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-13-report.md +25 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-2-brief.md +16 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-2-report.md +60 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-3-brief.md +15 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-3-report.md +77 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-4-brief.md +15 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-4-report.md +61 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-5-brief.md +16 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-5-report.md +33 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-6-brief.md +17 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-6-report.md +68 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-7-brief.md +15 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-7-report.md +55 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-8-brief.md +16 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-8-report.md +123 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-9-brief.md +8 -0
- csv_to_db_py-0.1.0/.superpowers/sdd/2026-10-08-csv-to-db-hardening/task-9-report.md +16 -0
- csv_to_db_py-0.1.0/.tool-versions +1 -0
- csv_to_db_py-0.1.0/.vscode/launch.json +24 -0
- csv_to_db_py-0.1.0/LICENSE.md +22 -0
- csv_to_db_py-0.1.0/PKG-INFO +276 -0
- csv_to_db_py-0.1.0/README.md +254 -0
- csv_to_db_py-0.1.0/compose.yml +11 -0
- csv_to_db_py-0.1.0/csv_to_db_py/__init__.py +4 -0
- csv_to_db_py-0.1.0/csv_to_db_py/config.py +44 -0
- csv_to_db_py-0.1.0/csv_to_db_py/core.py +90 -0
- csv_to_db_py-0.1.0/csv_to_db_py/db_connectors/__init__.py +5 -0
- csv_to_db_py-0.1.0/csv_to_db_py/db_connectors/base.py +14 -0
- csv_to_db_py-0.1.0/csv_to_db_py/db_connectors/mssql.py +17 -0
- csv_to_db_py-0.1.0/csv_to_db_py/db_connectors/mysql.py +16 -0
- csv_to_db_py-0.1.0/csv_to_db_py/db_connectors/oracle.py +17 -0
- csv_to_db_py-0.1.0/csv_to_db_py/db_connectors/postgres.py +17 -0
- csv_to_db_py-0.1.0/csv_to_db_py/logger.py +19 -0
- csv_to_db_py-0.1.0/csv_to_db_py/main.py +32 -0
- csv_to_db_py-0.1.0/csv_to_db_py/utils/__init__.py +7 -0
- csv_to_db_py-0.1.0/csv_to_db_py/utils/cleaned_csv.py +105 -0
- csv_to_db_py-0.1.0/csv_to_db_py/utils/csv_loader.py +265 -0
- csv_to_db_py-0.1.0/csv_to_db_py/utils/table_creator.py +19 -0
- csv_to_db_py-0.1.0/docs/superpowers/plans/2026-10-08-csv-to-db-hardening.md +206 -0
- csv_to_db_py-0.1.0/docs/superpowers/plans/2026-10-08-split-lib-cli.md +300 -0
- csv_to_db_py-0.1.0/input/test.csv +2 -0
- csv_to_db_py-0.1.0/mainConfig.json.example-flexible +15 -0
- csv_to_db_py-0.1.0/mainConfig.json.example-strict +15 -0
- csv_to_db_py-0.1.0/mainConfig.json.template +15 -0
- csv_to_db_py-0.1.0/pyproject.toml +50 -0
- csv_to_db_py-0.1.0/tests/date_formats_test.csv +11 -0
- csv_to_db_py-0.1.0/tests/test_batch_insertion.py +34 -0
- csv_to_db_py-0.1.0/tests/test_cli.py +21 -0
- csv_to_db_py-0.1.0/tests/test_config.py +53 -0
- csv_to_db_py-0.1.0/tests/test_connectors.py +36 -0
- csv_to_db_py-0.1.0/tests/test_core.py +52 -0
- csv_to_db_py-0.1.0/tests/test_datetime_convert.py +32 -0
- csv_to_db_py-0.1.0/tests/test_datetime_detection.py +48 -0
- csv_to_db_py-0.1.0/tests/test_delimiter.py +29 -0
- csv_to_db_py-0.1.0/tests/test_errors.py +100 -0
- csv_to_db_py-0.1.0/tests/test_filter.py +34 -0
- csv_to_db_py-0.1.0/tests/test_identifiers.py +48 -0
- csv_to_db_py-0.1.0/uv.lock +747 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- '[0-9]*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: astral-sh/setup-uv@v6
|
|
18
|
+
- run: uv build
|
|
19
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
ruff-format:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
container:
|
|
13
|
+
image: python:3.13-slim
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- name: install ruff
|
|
17
|
+
run: pip install ruff
|
|
18
|
+
- name: lint
|
|
19
|
+
run: ruff format --check
|
|
20
|
+
|
|
21
|
+
ruff-check:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
container:
|
|
24
|
+
image: python:3.13-slim
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- name: install ruff
|
|
28
|
+
run: pip install ruff
|
|
29
|
+
- name: lint
|
|
30
|
+
run: ruff check
|
|
31
|
+
|
|
32
|
+
test:
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
container:
|
|
35
|
+
image: python:3.13-slim
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- name: install uv
|
|
39
|
+
run: pip install uv
|
|
40
|
+
- name: install dependencies
|
|
41
|
+
run: uv sync --dev
|
|
42
|
+
- name: run tests
|
|
43
|
+
run: uv run pytest
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
mainConfig.json
|
|
2
|
+
|
|
3
|
+
# Python
|
|
4
|
+
__pycache__/
|
|
5
|
+
*.py[cod]
|
|
6
|
+
*$py.class
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
build/
|
|
11
|
+
dist/
|
|
12
|
+
*.egg-info/
|
|
13
|
+
|
|
14
|
+
# Environments
|
|
15
|
+
.env
|
|
16
|
+
.venv
|
|
17
|
+
venv/
|
|
18
|
+
|
|
19
|
+
# Ruff
|
|
20
|
+
.ruff_cache/
|
|
21
|
+
|
|
22
|
+
# Logs
|
|
23
|
+
*.log
|
|
24
|
+
|
|
25
|
+
.serena/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Final Review — Fix Report
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-08
|
|
4
|
+
Branch: `fixes` (fix wave on top of fc851e2)
|
|
5
|
+
Scope: whole-branch final review findings (2 Important + minor batch)
|
|
6
|
+
|
|
7
|
+
## Important 1 — Schema drift destroys old data before insert
|
|
8
|
+
|
|
9
|
+
**File:** `csv_to_db_py/utils/csv_loader.py`
|
|
10
|
+
|
|
11
|
+
`_truncate_if_exists` now takes `expected_columns`. When the table exists it
|
|
12
|
+
compares the DB column names (`inspect(engine).get_columns(table_name)` →
|
|
13
|
+
`.name`) against the expected columns **before** any `TRUNCATE`. On mismatch it
|
|
14
|
+
raises a `ValueError` explaining the schema drift and suggesting
|
|
15
|
+
`DROP TABLE ... CASCADE` + recreating dependent views; nothing is truncated.
|
|
16
|
+
Only when the names match is the table truncated. Return contract unchanged:
|
|
17
|
+
`True` if truncated, `False` if the table did not exist.
|
|
18
|
+
|
|
19
|
+
Call site updated in `overwrite_table_with_csv_data` to pass `csv_data.columns`.
|
|
20
|
+
|
|
21
|
+
### Column-name comparison behavior (checked)
|
|
22
|
+
|
|
23
|
+
`create_table_from_csv` builds its `CREATE TABLE IF NOT EXISTS` with
|
|
24
|
+
`quote_identifier(column)` (double-quoted identifiers) over the already
|
|
25
|
+
normalized `dataframe.columns`. Quoted identifiers preserve the exact case on
|
|
26
|
+
Postgres, so on the normal overwrite path `get_columns(...)` returns the very
|
|
27
|
+
same names as `df.columns`. I therefore compare **exact** sorted name lists
|
|
28
|
+
without normalization. Rationale: the guard exists to avoid destroying data
|
|
29
|
+
when layouts differ; a normalized (fuzzy) comparison could mask a genuine
|
|
30
|
+
rename (e.g. `col name` → `colname` normalizing to the same key) and wrongly
|
|
31
|
+
truncate. Exact comparison is the correct, stricter choice. No normalization
|
|
32
|
+
applied.
|
|
33
|
+
|
|
34
|
+
A one-line `ponytail:` comment documents that TYPE drift is still not guarded
|
|
35
|
+
(it still fails loudly after truncate), which is acceptable since the name
|
|
36
|
+
guard covers the documented case.
|
|
37
|
+
|
|
38
|
+
**Tests** (`tests/test_errors.py`, +2 new):
|
|
39
|
+
- `test_truncate_raises_on_schema_drift_without_truncating`: stub inspector
|
|
40
|
+
with `has_table` → True and `get_columns` returning a column different from
|
|
41
|
+
the dataframe's → `_truncate_if_exists` raises `ValueError`; the stub engine
|
|
42
|
+
uses the existing `BoomConn` (raises `RuntimeError` on execute), so a
|
|
43
|
+
`ValueError` proves TRUNCATE never ran.
|
|
44
|
+
- `test_truncate_executes_when_columns_match`: stub inspector whose columns
|
|
45
|
+
match → TRUNCATE executes (asserted via a counting connection) and returns
|
|
46
|
+
`True`.
|
|
47
|
+
- Existing `test_truncate_if_exists_propagates_execute_error` updated: the
|
|
48
|
+
`FakeInspector` now also returns `get_columns` matching `["col"]`.
|
|
49
|
+
|
|
50
|
+
## Important 2 — README Testing section stale
|
|
51
|
+
|
|
52
|
+
`README.md` Testing section now runs `uv run pytest` instead of
|
|
53
|
+
`uv run python tests/test_datetime_detection.py` (that file is a pytest module
|
|
54
|
+
without `__main__`), and the prose reflects the pytest reality.
|
|
55
|
+
|
|
56
|
+
## Minor batch
|
|
57
|
+
|
|
58
|
+
1. `csv_to_db_py/config.py`: `validate_config` guards `DATABASE_CONFIG` with
|
|
59
|
+
`isinstance(cfg.get("DATABASE_CONFIG"), dict)` → `ValueError` (was
|
|
60
|
+
AttributeError on `.get` of a non-dict). Error message concatenation merged
|
|
61
|
+
into a single f-string.
|
|
62
|
+
2. `tests/test_datetime_detection.py`: `TEST_FILE` now
|
|
63
|
+
`Path(__file__).parent / "date_formats_test.csv"` (CWD-independent).
|
|
64
|
+
3. `csv_to_db_py/main.py`: the two
|
|
65
|
+
`from csv_to_db_py.utils.cleaned_csv import ...` lines merged into one.
|
|
66
|
+
4. `csv_to_db_py/main.py`: `parse_args` annotated
|
|
67
|
+
`-> argparse.Namespace`.
|
|
68
|
+
5. `csv_to_db_py/utils/cleaned_csv.py`: `apply_filter` annotated
|
|
69
|
+
`(df: pl.DataFrame, filter_config: dict) -> pl.DataFrame`.
|
|
70
|
+
6. `README.md`: Table Overwrite Strategy reworded — table is always
|
|
71
|
+
pre-created by `create_table_from_csv` (no longer "created automatically by
|
|
72
|
+
`to_sql`"); column-name drift now blocks before truncating, type drift
|
|
73
|
+
still fails loudly after truncate.
|
|
74
|
+
7. `csv_to_db_py/utils/csv_loader.py`: stale "au moins 90%" comments replaced
|
|
75
|
+
with the configurable `datetime_detection_threshold` wording; one-line
|
|
76
|
+
docstring added to `convert_datetime_columns`.
|
|
77
|
+
|
|
78
|
+
## Verification
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
$ UV_PROJECT_ENVIRONMENT=/tmp/uv/csv-to-db-py uv run pytest -q
|
|
82
|
+
47 passed, 80 warnings in 0.40s
|
|
83
|
+
|
|
84
|
+
$ UV_PROJECT_ENVIRONMENT=/tmp/uv/csv-to-db-py uv run ruff check .
|
|
85
|
+
All checks passed! (Ruff: No issues found)
|
|
86
|
+
|
|
87
|
+
$ UV_PROJECT_ENVIRONMENT=/tmp/uv/csv-to-db-py uv run ruff format .
|
|
88
|
+
24 files left unchanged
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Baseline before the fix wave: 45 passed → 47 after (2 new drift tests).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
docs/superpowers/plans/2026-10-08-csv-to-db-hardening.md
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# SDD ledger — plan: docs/superpowers/plans/2026-10-08-csv-to-db-hardening.md
|
|
2
|
+
|
|
3
|
+
## Pre-flight scan
|
|
4
|
+
|
|
5
|
+
| Tasks | Shared file | What one produces / other consumes | Found |
|
|
6
|
+
|---|---|---|---|
|
|
7
|
+
| T1 → T7 | `csv_to_db_py/main.py` | imports (T1) then argparse (T7) | sequential, fine |
|
|
8
|
+
| T1 → T5 | `table_creator.py`, `csv_loader.py` | import fixes, then error handling | sequential, fine |
|
|
9
|
+
| T5 → T6 | `csv_loader.py` | error propagation, then datetime refactor (different functions) | sequential, fine |
|
|
10
|
+
| T6 → T7 | `csv_loader.py` | `convert_datetime_columns`, then delete `polars_type_to_sql` | sequential, fine |
|
|
11
|
+
| T4 → T11 | `cleaned_csv.py` | `quote_identifier`, then `apply_filter` (different functions) | sequential, fine |
|
|
12
|
+
| T2 → T3 | `config.py` + tests | validation, then tests import prod modules | **CONFLICT: config.py reads `../mainConfig.json` at import; file is gitignored → absent in CI → tests cannot import** |
|
|
13
|
+
| T3 → T8 | `pyproject.toml` | pytest (dev), then drivers (deps) | sequential, fine |
|
|
14
|
+
| T6 test | config threshold | test needs threshold 0.7; local config has no key → default 1.0 | **NOTE: T6 test must monkeypatch `config["datetime_detection_threshold"] = 0.7`** |
|
|
15
|
+
| T9 | `compose.yml` | file is untracked (`?? compose.yml`) | commit will `git add` it whole; expected |
|
|
16
|
+
|
|
17
|
+
## Pre-flight rulings
|
|
18
|
+
|
|
19
|
+
- `Ruling: config import resilience` — config.py must fall back to `mainConfig.json.example-strict` when `mainConfig.json` is absent, then validate. Without it, tests and CI crash on `import csv_to_db_py.config` (gitignored config missing in CI, and installed package can't find `../mainConfig.json`). Amend Task 2. — Cost if wrong: small rework in T2.
|
|
20
|
+
- `Ruling: T6 test threshold` — T6 test monkeypatches `config["datetime_detection_threshold"] = 0.7` before calling `convert_datetime_columns`; carried in T6 dispatch. — Cost if wrong: test silently uses default 1.0 and fails.
|
|
21
|
+
|
|
22
|
+
## Tasks
|
|
23
|
+
|
|
24
|
+
Task 1: pending
|
|
25
|
+
|
|
26
|
+
Task 1: complete (commits 7ffe98c..f7751b0, review clean)
|
|
27
|
+
Task 1: minor (deferred): main.py:101-102 two csv_to_db_py.utils.cleaned_csv import lines could merge into one
|
|
28
|
+
|
|
29
|
+
Task 2: complete (commits f7751b0..02798e6, review clean)
|
|
30
|
+
Task 2: minor (deferred): config.py:28 DATABASE_CONFIG non-dict would raise AttributeError not ValueError; f-string for error message; fallback load path not covered by test
|
|
31
|
+
|
|
32
|
+
Task 3: complete (commits 02798e6..bd3e9d5, review clean; 22 tests passing confirmed by controller)
|
|
33
|
+
Task 3: minor (deferred): TEST_FILE path is CWD-relative (use Path(__file__).parent); batch test replicates prod formula (accepted, no importable helper)
|
|
34
|
+
|
|
35
|
+
Task 4: complete (commits bd3e9d5..ab9ee61, review clean)
|
|
36
|
+
Task 4: minor (deferred): long f-string in table_creator.py:86 readability
|
|
37
|
+
|
|
38
|
+
Task 5: complete (commits ab9ee61..55479cd, review clean)
|
|
39
|
+
Task 5: minor (deferred): table_creator.py has pre-existing duplicate `columns = dataframe.columns` assignment (out of scope)
|
|
40
|
+
|
|
41
|
+
Task 6: complete (commits 55479cd..27c87bb, review clean; fix round 1/5: test data 4 values at threshold 0.7 per ruling)
|
|
42
|
+
Task 6: minor (deferred): stale "90%" comments in csv_loader.py:110,172 (pre-existing); convert_datetime_columns lacks docstring
|
|
43
|
+
|
|
44
|
+
Task 7: complete (commits 27c87bb..11102ec, review clean)
|
|
45
|
+
Task 7: minor (deferred): parse_args lacks return type annotation (cosmetic)
|
|
46
|
+
|
|
47
|
+
Task 8: fix round 1/5 (oracle driver) — in progress
|
|
48
|
+
Task 8: Ruling: cx_Oracle cannot build on Python 3.13 (deprecated C extension, no cp313 wheel; sandbox build failed on missing pkg_resources). Its official successor python-oracledb ships cp313 wheels and SQLAlchemy supports dialect `oracle+oracledb`. Replace cx_oracle with oracledb so the connector installs everywhere (including CI uv sync) and the oracle test can run. — Cost if wrong: dialect name differs from some users' expectations; small.
|
|
49
|
+
|
|
50
|
+
Task 8: complete (commits 11102ec..f08c415, review clean; fix round 1/5: cx_oracle → oracledb per ruling)
|
|
51
|
+
Task 8: minor (deferred): make_url identity vs string round-trip in connector test (matches brief, adequate)
|
|
52
|
+
|
|
53
|
+
Task 9: complete (commits f08c415..8593195, review clean)
|
|
54
|
+
|
|
55
|
+
Task 10: complete (commits 8593195..49aa2f3, review clean)
|
|
56
|
+
|
|
57
|
+
Task 11: complete (commits 49aa2f3..ff80dc8, review clean)
|
|
58
|
+
Task 11: minor (deferred): apply_filter lacks type hints; FILTER empty-string value now runs filter (was truthy-skipped) — harmless
|
|
59
|
+
|
|
60
|
+
Task 12: complete (commits ff80dc8..dbb469e, review clean)
|
|
61
|
+
|
|
62
|
+
Task 13: complete (commits dbb469e..fc851e2, review clean)
|
|
63
|
+
Task 13: minor (deferred): README "Good for most cases" 100000 framing vs new 10000 default; launch.json windows python path (pre-existing)
|
|
64
|
+
ALL TASKS COMPLETE. Launching final whole-branch review (base 7ffe98c, head fc851e2).
|
|
65
|
+
|
|
66
|
+
Final review: "With fixes" — 2 Important + minor batch. Dispatching ONE fix subagent (fix base fc851e2).
|
|
67
|
+
|
|
68
|
+
Final review fix wave: complete (fc851e2..9ee3e7a, re-review clean — all 9 findings addressed, no new Critical/Important breakage)
|
|
69
|
+
Out-of-scope note for user: quote_identifier uses postgres double-quote syntax on all backends (MySQL expects backticks) — pre-existing, not introduced by this branch.
|
|
70
|
+
Final review: clean. Workspace cleanup next.
|