execsql2 2.15.7__py3-none-any.whl → 2.15.8__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.
Files changed (22) hide show
  1. execsql/metacommands/upsert.py +20 -10
  2. {execsql2-2.15.7.dist-info → execsql2-2.15.8.dist-info}/METADATA +3 -3
  3. {execsql2-2.15.7.dist-info → execsql2-2.15.8.dist-info}/RECORD +22 -22
  4. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/README.md +0 -0
  5. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/config_settings.sqlite +0 -0
  6. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
  7. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/execsql.conf +0 -0
  8. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/make_config_db.sql +0 -0
  9. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/md_compare.sql +0 -0
  10. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/md_glossary.sql +0 -0
  11. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/md_upsert.sql +0 -0
  12. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/pg_compare.sql +0 -0
  13. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/pg_glossary.sql +0 -0
  14. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/pg_upsert.sql +0 -0
  15. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/script_template.sql +0 -0
  16. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/ss_compare.sql +0 -0
  17. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/ss_glossary.sql +0 -0
  18. {execsql2-2.15.7.data → execsql2-2.15.8.data}/data/execsql2_extras/ss_upsert.sql +0 -0
  19. {execsql2-2.15.7.dist-info → execsql2-2.15.8.dist-info}/WHEEL +0 -0
  20. {execsql2-2.15.7.dist-info → execsql2-2.15.8.dist-info}/entry_points.txt +0 -0
  21. {execsql2-2.15.7.dist-info → execsql2-2.15.8.dist-info}/licenses/LICENSE.txt +0 -0
  22. {execsql2-2.15.7.dist-info → execsql2-2.15.8.dist-info}/licenses/NOTICE +0 -0
@@ -26,11 +26,11 @@ from execsql.utils.errors import exception_desc
26
26
 
27
27
  _KW_METHOD = re.compile(r"\bMETHOD\s+(upsert|update|insert)\b", re.IGNORECASE)
28
28
  _KW_EXCLUDE = re.compile(
29
- r"\bEXCLUDE\s+([\w\s,]+?)(?=\s+(?:METHOD|COMMIT|INTERACTIVE|COMPACT|EXCLUDE_NULL|LOGFILE|CLEANUP|EXPORT_FAILURES|EXPORT_FORMAT|EXPORT_MAX_ROWS)\b|\s*$)",
29
+ r"\bEXCLUDE\s+([\w\s,]+?)(?=\s+(?:METHOD|COMMIT|INTERACTIVE|COMPACT|EXCLUDE_NULL|LOGFILE|CLEANUP|EXPORT_FAILURES|EXPORT_FORMAT|EXPORT_MAX_ROWS|STRICT_COLUMNS)\b|\s*$)",
30
30
  re.IGNORECASE,
31
31
  )
32
32
  _KW_EXCLUDE_NULL = re.compile(
33
- r"\bEXCLUDE_NULL\s+([\w\s,]+?)(?=\s+(?:METHOD|COMMIT|INTERACTIVE|COMPACT|EXCLUDE|LOGFILE|CLEANUP|EXPORT_FAILURES|EXPORT_FORMAT|EXPORT_MAX_ROWS)\b|\s*$)",
33
+ r"\bEXCLUDE_NULL\s+([\w\s,]+?)(?=\s+(?:METHOD|COMMIT|INTERACTIVE|COMPACT|EXCLUDE|LOGFILE|CLEANUP|EXPORT_FAILURES|EXPORT_FORMAT|EXPORT_MAX_ROWS|STRICT_COLUMNS)\b|\s*$)",
34
34
  re.IGNORECASE,
35
35
  )
36
36
  _KW_COMMIT = re.compile(r"\bCOMMIT\b", re.IGNORECASE)
@@ -44,10 +44,11 @@ _KW_EXPORT_FAILURES = re.compile(
44
44
  )
45
45
  _KW_EXPORT_FORMAT = re.compile(r"\bEXPORT_FORMAT\s+(\S+)", re.IGNORECASE)
46
46
  _KW_EXPORT_MAX_ROWS = re.compile(r"\bEXPORT_MAX_ROWS\s+(\S+)", re.IGNORECASE)
47
+ _KW_STRICT_COLUMNS = re.compile(r"\bSTRICT_COLUMNS\b", re.IGNORECASE)
47
48
 
48
49
  # All recognized keywords — used to split table names from options.
49
50
  _ALL_KEYWORDS = re.compile(
50
- r"\b(?:METHOD|COMMIT|INTERACTIVE|COMPACT|EXCLUDE_NULL|EXCLUDE|LOGFILE|CLEANUP|EXPORT_FAILURES|EXPORT_FORMAT|EXPORT_MAX_ROWS)\b",
51
+ r"\b(?:METHOD|COMMIT|INTERACTIVE|COMPACT|EXCLUDE_NULL|EXCLUDE|LOGFILE|CLEANUP|EXPORT_FAILURES|EXPORT_FORMAT|EXPORT_MAX_ROWS|STRICT_COLUMNS)\b",
51
52
  re.IGNORECASE,
52
53
  )
53
54
 
@@ -145,6 +146,7 @@ def _parse_tables_and_options(tail: str) -> dict[str, Any]:
145
146
  "export_failures": export_failures,
146
147
  "export_format": export_format,
147
148
  "export_max_rows": export_max_rows,
149
+ "strict_columns": bool(_KW_STRICT_COLUMNS.search(opts_part)),
148
150
  }
149
151
 
150
152
 
@@ -191,6 +193,9 @@ def _set_subvars(result: Any) -> None:
191
193
  sv("$PG_UPSERT_STARTED_AT", result.started_at)
192
194
  sv("$PG_UPSERT_FINISHED_AT", result.finished_at)
193
195
  sv("$PG_UPSERT_RESULT_JSON", json.dumps(result.to_dict(), separators=(",", ":")))
196
+ # Warnings: tables with WARNING-level findings (still qa_passed=True).
197
+ warned_tables = [t.table_name for t in result.tables if t.qa_warnings]
198
+ sv("$PG_UPSERT_QA_WARNINGS", ", ".join(warned_tables) if warned_tables else "")
194
199
  # Default export path subvar to empty; _export_failures_if_requested
195
200
  # will overwrite it with the actual path if an export was produced.
196
201
  sv("$PG_UPSERT_EXPORT_PATH", "")
@@ -230,16 +235,20 @@ def _require_postgres(db: Any, metacommandline: str | None) -> None:
230
235
  )
231
236
 
232
237
 
233
- def _build_result_from_qa_errors(ups: Any) -> Any:
234
- """Build an UpsertResult from ``ups.qa_errors`` after a QA/CHECK run."""
238
+ def _build_result_from_qa_findings(ups: Any) -> Any:
239
+ """Build an UpsertResult from ``ups.qa_findings`` after a QA/CHECK run.
240
+
241
+ Uses ``qa_findings`` (all findings: errors + warnings) so that
242
+ ``$PG_UPSERT_RESULT_JSON`` includes both severity levels.
243
+ """
235
244
  from pg_upsert.models import TableResult, UpsertResult
236
245
 
237
246
  table_results: dict[str, Any] = {}
238
247
  for table_name in ups.tables:
239
248
  table_results[table_name] = TableResult(table_name=table_name)
240
- for err in ups.qa_errors:
241
- if err.table in table_results:
242
- table_results[err.table].qa_errors.append(err)
249
+ for finding in ups.qa_findings:
250
+ if finding.table in table_results:
251
+ table_results[finding.table]._qa_findings.append(finding)
243
252
  return UpsertResult(
244
253
  tables=list(table_results.values()),
245
254
  committed=False,
@@ -289,6 +298,7 @@ def _create_pgupsert(
289
298
  "upsert_method": opts["method"],
290
299
  "exclude_cols": opts["exclude_cols"],
291
300
  "exclude_null_check_cols": opts["exclude_null_check_cols"],
301
+ "strict_columns": opts.get("strict_columns", False),
292
302
  "ui_mode": ui_mode,
293
303
  "callback": _make_callback(),
294
304
  }
@@ -508,7 +518,7 @@ def x_pg_upsert_qa(**kwargs: Any) -> None:
508
518
  finally:
509
519
  _detach_log_handlers(loggers, handlers, prev_levels)
510
520
 
511
- result = _build_result_from_qa_errors(ups)
521
+ result = _build_result_from_qa_findings(ups)
512
522
  _set_subvars(result)
513
523
  _export_failures_if_requested(result, opts, metacommandline)
514
524
  if opts.get("cleanup"):
@@ -551,7 +561,7 @@ def x_pg_upsert_check(**kwargs: Any) -> None:
551
561
  finally:
552
562
  _detach_log_handlers(loggers, handlers, prev_levels)
553
563
 
554
- result = _build_result_from_qa_errors(ups)
564
+ result = _build_result_from_qa_findings(ups)
555
565
  _set_subvars(result)
556
566
  _export_failures_if_requested(result, opts, metacommandline)
557
567
  if opts.get("cleanup"):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: execsql2
3
- Version: 2.15.7
3
+ Version: 2.15.8
4
4
  Summary: Runs a SQL script against a PostgreSQL, SQLite, MariaDB/MySQL, DuckDB, Firebird, MS-Access, MS-SQL-Server, or Oracle database, or an ODBC DSN. Provides metacommands to import and export data, copy data between databases, conditionally execute SQL and metacommands, and dynamically alter SQL and metacommands with substitution variables.
5
5
  Project-URL: Homepage, https://execsql2.readthedocs.io
6
6
  Project-URL: Repository, https://github.com/geocoug/execsql
@@ -52,7 +52,7 @@ Requires-Dist: keyring; extra == 'all'
52
52
  Requires-Dist: odfpy; extra == 'all'
53
53
  Requires-Dist: openpyxl; extra == 'all'
54
54
  Requires-Dist: oracledb; extra == 'all'
55
- Requires-Dist: pg-upsert>=1.21.0; extra == 'all'
55
+ Requires-Dist: pg-upsert>=1.22.0; extra == 'all'
56
56
  Requires-Dist: polars; extra == 'all'
57
57
  Requires-Dist: psycopg2-binary; extra == 'all'
58
58
  Requires-Dist: pymysql; extra == 'all'
@@ -117,7 +117,7 @@ Requires-Dist: oracledb; extra == 'oracle'
117
117
  Provides-Extra: postgres
118
118
  Requires-Dist: psycopg2-binary; extra == 'postgres'
119
119
  Provides-Extra: upsert
120
- Requires-Dist: pg-upsert>=1.21.0; extra == 'upsert'
120
+ Requires-Dist: pg-upsert>=1.22.0; extra == 'upsert'
121
121
  Description-Content-Type: text/markdown
122
122
 
123
123
  > [!NOTE]
@@ -76,7 +76,7 @@ execsql/metacommands/io_write.py,sha256=NpL2aYGfBpbqmPpYsqniYltYfd_SCA1EQz3_4qSd
76
76
  execsql/metacommands/prompt.py,sha256=E2e7q4pxbl_wEBrhco0B2gm5hO_HG3rNIF75PLdTgGg,36767
77
77
  execsql/metacommands/script_ext.py,sha256=TUgAldB2LSJAwZrCvDDi804hQ1d9BDQD2GDqHNPVOcM,2280
78
78
  execsql/metacommands/system.py,sha256=azRbv_P8l0t8BkDM9bmAUkhpnLSLHSCcmByqs-a3FxQ,7352
79
- execsql/metacommands/upsert.py,sha256=imXKk2A9TuG4rS_mr40_g2A1IY9iOMKhFYkAm4n3dFk,19214
79
+ execsql/metacommands/upsert.py,sha256=DxtAhGpC6qD--sk932u40cbfQfvFlV-SXnV7WUTwk_8,19858
80
80
  execsql/script/__init__.py,sha256=HbVQmQEVn4gBtzwy5_nlbDGuRnbWd4dI4nG-q1KyBxs,3498
81
81
  execsql/script/control.py,sha256=s-1eZdGARM6H1FwZ6VDdO_f50j7bvvRtTHesfUm9tbc,6144
82
82
  execsql/script/engine.py,sha256=HDlwm3_EqU6A4Z4O27dqQRvkpIACUuzYh3dZZAc8C98,43130
@@ -93,24 +93,24 @@ execsql/utils/numeric.py,sha256=xh02ANSRk3nUpQ-rtm66ILoMqoi7HtzCoRMIOT9U8QI,1570
93
93
  execsql/utils/regex.py,sha256=diEzTZqU_HHwVMadPAvN1Vgzhl7I03eVaEFGCXyGGL8,3770
94
94
  execsql/utils/strings.py,sha256=5Dvzrk-9SIw2lpxXZQkiJbNyo1sy7iXXAtSULlZ0KG8,8488
95
95
  execsql/utils/timer.py,sha256=eDYf5VzCNFk7oo90InJucUm3XcBdhYMogjZMqeg9xzc,1899
96
- execsql2-2.15.7.data/data/execsql2_extras/README.md,sha256=sxwVyU0ZahCfANv56LahkyuM505kFjrMhe-1SvWE69E,4845
97
- execsql2-2.15.7.data/data/execsql2_extras/config_settings.sqlite,sha256=aY5cxR7Q7J6zJ4bC9lu5mHUrhy211Cq3MNKPQVCt02E,20480
98
- execsql2-2.15.7.data/data/execsql2_extras/example_config_prompt.sql,sha256=SY3Jxn1qcVm4kPW9xmmTfknHfvURXmeEYTbRjYrjGSw,7487
99
- execsql2-2.15.7.data/data/execsql2_extras/execsql.conf,sha256=_45iJ-KWZnB8uMW_gEg067MM5pmGJ-dVl7VbAZMunAE,9530
100
- execsql2-2.15.7.data/data/execsql2_extras/make_config_db.sql,sha256=WwyC6dK-Eh5CAVppiBCDHqiI1_wEI9U95Ytpr4lsZkg,8726
101
- execsql2-2.15.7.data/data/execsql2_extras/md_compare.sql,sha256=B8Wd7LZ0vnMY2qvA139JIEBkPObgRH2i5xj6PejTQt8,24092
102
- execsql2-2.15.7.data/data/execsql2_extras/md_glossary.sql,sha256=DJRHcU5NbFpxTTX-IwH3yRlsboj1q6BBGrUAHKn4Cuo,10796
103
- execsql2-2.15.7.data/data/execsql2_extras/md_upsert.sql,sha256=v_7GbWh_N1mBTmw3gvTrkagOVp2q0KmXvM8hE-DlFxY,112524
104
- execsql2-2.15.7.data/data/execsql2_extras/pg_compare.sql,sha256=9dWa8hnfy5dVJI-z2iGpd9JzQmI4j2ziMlEdpnr66ro,24352
105
- execsql2-2.15.7.data/data/execsql2_extras/pg_glossary.sql,sha256=pKjIIDsROAgJq2H-1qNEcRMAWManivcZ_AEVHzUUlic,9908
106
- execsql2-2.15.7.data/data/execsql2_extras/pg_upsert.sql,sha256=k7AFiGTLBy3nf-qO5QIaZrEYTAKvdxxU3JDLx9jqkzs,108315
107
- execsql2-2.15.7.data/data/execsql2_extras/script_template.sql,sha256=1Estacb_vm1FgK41k_G9nuduP1yiA-fQ1Kn4Z4mv5Ao,11153
108
- execsql2-2.15.7.data/data/execsql2_extras/ss_compare.sql,sha256=TsVxWm3cEpR5-EiMYXNhtaY0arSNeKZhsJdHdLA7xeI,24833
109
- execsql2-2.15.7.data/data/execsql2_extras/ss_glossary.sql,sha256=cLM7nN8JOIu9ZVP9oY9qdSK3hrnWJiDcX6nZmQQbQWI,13065
110
- execsql2-2.15.7.data/data/execsql2_extras/ss_upsert.sql,sha256=BCqmBykXBF-BpCgOFeG1qhf2XfScKsxPD17wd1hYfHw,120647
111
- execsql2-2.15.7.dist-info/METADATA,sha256=EJ8BkbT-M-KMojwtJD1l7vTvSWj7tFBJ-JQ4XTZWC-s,18114
112
- execsql2-2.15.7.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
113
- execsql2-2.15.7.dist-info/entry_points.txt,sha256=sUOxkM-dN1eBGGpSpDLsAaE0yNXYQKWZAfxPOlMkQyk,90
114
- execsql2-2.15.7.dist-info/licenses/LICENSE.txt,sha256=LBdhuxejF8_bLCHZ2kWfmDXpDGUu914Gbd6_3JjCRe0,676
115
- execsql2-2.15.7.dist-info/licenses/NOTICE,sha256=sqVrM73Ys9zfvWC_P797lHfTnoPW_ETeBSrUTFaob0A,339
116
- execsql2-2.15.7.dist-info/RECORD,,
96
+ execsql2-2.15.8.data/data/execsql2_extras/README.md,sha256=sxwVyU0ZahCfANv56LahkyuM505kFjrMhe-1SvWE69E,4845
97
+ execsql2-2.15.8.data/data/execsql2_extras/config_settings.sqlite,sha256=aY5cxR7Q7J6zJ4bC9lu5mHUrhy211Cq3MNKPQVCt02E,20480
98
+ execsql2-2.15.8.data/data/execsql2_extras/example_config_prompt.sql,sha256=SY3Jxn1qcVm4kPW9xmmTfknHfvURXmeEYTbRjYrjGSw,7487
99
+ execsql2-2.15.8.data/data/execsql2_extras/execsql.conf,sha256=_45iJ-KWZnB8uMW_gEg067MM5pmGJ-dVl7VbAZMunAE,9530
100
+ execsql2-2.15.8.data/data/execsql2_extras/make_config_db.sql,sha256=WwyC6dK-Eh5CAVppiBCDHqiI1_wEI9U95Ytpr4lsZkg,8726
101
+ execsql2-2.15.8.data/data/execsql2_extras/md_compare.sql,sha256=B8Wd7LZ0vnMY2qvA139JIEBkPObgRH2i5xj6PejTQt8,24092
102
+ execsql2-2.15.8.data/data/execsql2_extras/md_glossary.sql,sha256=DJRHcU5NbFpxTTX-IwH3yRlsboj1q6BBGrUAHKn4Cuo,10796
103
+ execsql2-2.15.8.data/data/execsql2_extras/md_upsert.sql,sha256=v_7GbWh_N1mBTmw3gvTrkagOVp2q0KmXvM8hE-DlFxY,112524
104
+ execsql2-2.15.8.data/data/execsql2_extras/pg_compare.sql,sha256=9dWa8hnfy5dVJI-z2iGpd9JzQmI4j2ziMlEdpnr66ro,24352
105
+ execsql2-2.15.8.data/data/execsql2_extras/pg_glossary.sql,sha256=pKjIIDsROAgJq2H-1qNEcRMAWManivcZ_AEVHzUUlic,9908
106
+ execsql2-2.15.8.data/data/execsql2_extras/pg_upsert.sql,sha256=k7AFiGTLBy3nf-qO5QIaZrEYTAKvdxxU3JDLx9jqkzs,108315
107
+ execsql2-2.15.8.data/data/execsql2_extras/script_template.sql,sha256=1Estacb_vm1FgK41k_G9nuduP1yiA-fQ1Kn4Z4mv5Ao,11153
108
+ execsql2-2.15.8.data/data/execsql2_extras/ss_compare.sql,sha256=TsVxWm3cEpR5-EiMYXNhtaY0arSNeKZhsJdHdLA7xeI,24833
109
+ execsql2-2.15.8.data/data/execsql2_extras/ss_glossary.sql,sha256=cLM7nN8JOIu9ZVP9oY9qdSK3hrnWJiDcX6nZmQQbQWI,13065
110
+ execsql2-2.15.8.data/data/execsql2_extras/ss_upsert.sql,sha256=BCqmBykXBF-BpCgOFeG1qhf2XfScKsxPD17wd1hYfHw,120647
111
+ execsql2-2.15.8.dist-info/METADATA,sha256=7S2K-cQV9yOTxpKpB6ehIskUEjjKU9ZHTBpznumVi04,18114
112
+ execsql2-2.15.8.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
113
+ execsql2-2.15.8.dist-info/entry_points.txt,sha256=sUOxkM-dN1eBGGpSpDLsAaE0yNXYQKWZAfxPOlMkQyk,90
114
+ execsql2-2.15.8.dist-info/licenses/LICENSE.txt,sha256=LBdhuxejF8_bLCHZ2kWfmDXpDGUu914Gbd6_3JjCRe0,676
115
+ execsql2-2.15.8.dist-info/licenses/NOTICE,sha256=sqVrM73Ys9zfvWC_P797lHfTnoPW_ETeBSrUTFaob0A,339
116
+ execsql2-2.15.8.dist-info/RECORD,,