execsql2 2.12.5__py3-none-any.whl → 2.12.7__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.
- execsql/metacommands/upsert.py +28 -3
- {execsql2-2.12.5.dist-info → execsql2-2.12.7.dist-info}/METADATA +3 -3
- {execsql2-2.12.5.dist-info → execsql2-2.12.7.dist-info}/RECORD +22 -22
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/README.md +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/config_settings.sqlite +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/execsql.conf +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/make_config_db.sql +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/md_compare.sql +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/md_glossary.sql +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/md_upsert.sql +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/pg_compare.sql +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/pg_glossary.sql +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/pg_upsert.sql +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/script_template.sql +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/ss_compare.sql +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/ss_glossary.sql +0 -0
- {execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/ss_upsert.sql +0 -0
- {execsql2-2.12.5.dist-info → execsql2-2.12.7.dist-info}/WHEEL +0 -0
- {execsql2-2.12.5.dist-info → execsql2-2.12.7.dist-info}/entry_points.txt +0 -0
- {execsql2-2.12.5.dist-info → execsql2-2.12.7.dist-info}/licenses/LICENSE.txt +0 -0
- {execsql2-2.12.5.dist-info → execsql2-2.12.7.dist-info}/licenses/NOTICE +0 -0
execsql/metacommands/upsert.py
CHANGED
|
@@ -26,21 +26,22 @@ 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)\b|\s*$)",
|
|
29
|
+
r"\bEXCLUDE\s+([\w\s,]+?)(?=\s+(?:METHOD|COMMIT|INTERACTIVE|COMPACT|EXCLUDE_NULL|LOGFILE|CLEANUP)\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)\b|\s*$)",
|
|
33
|
+
r"\bEXCLUDE_NULL\s+([\w\s,]+?)(?=\s+(?:METHOD|COMMIT|INTERACTIVE|COMPACT|EXCLUDE|LOGFILE|CLEANUP)\b|\s*$)",
|
|
34
34
|
re.IGNORECASE,
|
|
35
35
|
)
|
|
36
36
|
_KW_COMMIT = re.compile(r"\bCOMMIT\b", re.IGNORECASE)
|
|
37
37
|
_KW_INTERACTIVE = re.compile(r"\bINTERACTIVE\b", re.IGNORECASE)
|
|
38
38
|
_KW_COMPACT = re.compile(r"\bCOMPACT\b", re.IGNORECASE)
|
|
39
|
+
_KW_CLEANUP = re.compile(r"\bCLEANUP\b", re.IGNORECASE)
|
|
39
40
|
_KW_LOGFILE = re.compile(r"""\bLOGFILE\s+(?:"([^"]+)"|'([^']+)'|(\S+))""", re.IGNORECASE)
|
|
40
41
|
|
|
41
42
|
# All recognized keywords — used to split table names from options.
|
|
42
43
|
_ALL_KEYWORDS = re.compile(
|
|
43
|
-
r"\b(?:METHOD|COMMIT|INTERACTIVE|COMPACT|EXCLUDE_NULL|EXCLUDE|LOGFILE)\b",
|
|
44
|
+
r"\b(?:METHOD|COMMIT|INTERACTIVE|COMPACT|EXCLUDE_NULL|EXCLUDE|LOGFILE|CLEANUP)\b",
|
|
44
45
|
re.IGNORECASE,
|
|
45
46
|
)
|
|
46
47
|
|
|
@@ -98,6 +99,7 @@ def _parse_tables_and_options(tail: str) -> dict[str, Any]:
|
|
|
98
99
|
"exclude_cols": exclude_cols,
|
|
99
100
|
"exclude_null_check_cols": exclude_null,
|
|
100
101
|
"logfile": logfile,
|
|
102
|
+
"cleanup": bool(_KW_CLEANUP.search(opts_part)),
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
|
|
@@ -210,6 +212,22 @@ def _build_result_from_qa_errors(ups: Any) -> Any:
|
|
|
210
212
|
)
|
|
211
213
|
|
|
212
214
|
|
|
215
|
+
def _make_callback() -> Any:
|
|
216
|
+
"""Return a pg-upsert pipeline callback that sets per-table subvars."""
|
|
217
|
+
from pg_upsert import CallbackEvent
|
|
218
|
+
|
|
219
|
+
def _on_event(event: Any) -> None:
|
|
220
|
+
sv = _state.subvars.add_substitution
|
|
221
|
+
sv("$PG_UPSERT_CURRENT_TABLE", event.table)
|
|
222
|
+
if event.event == CallbackEvent.QA_TABLE_COMPLETE:
|
|
223
|
+
sv("$PG_UPSERT_TABLE_QA_PASSED", str(event.qa_passed).upper())
|
|
224
|
+
elif event.event == CallbackEvent.UPSERT_TABLE_COMPLETE:
|
|
225
|
+
sv("$PG_UPSERT_TABLE_ROWS_UPDATED", str(event.rows_updated))
|
|
226
|
+
sv("$PG_UPSERT_TABLE_ROWS_INSERTED", str(event.rows_inserted))
|
|
227
|
+
|
|
228
|
+
return _on_event
|
|
229
|
+
|
|
230
|
+
|
|
213
231
|
def _create_pgupsert(
|
|
214
232
|
db: Any,
|
|
215
233
|
staging_schema: str,
|
|
@@ -235,6 +253,7 @@ def _create_pgupsert(
|
|
|
235
253
|
exclude_cols=opts["exclude_cols"],
|
|
236
254
|
exclude_null_check_cols=opts["exclude_null_check_cols"],
|
|
237
255
|
ui_mode=ui_mode,
|
|
256
|
+
callback=_make_callback(),
|
|
238
257
|
)
|
|
239
258
|
return ups
|
|
240
259
|
|
|
@@ -362,6 +381,8 @@ def x_pg_upsert(**kwargs: Any) -> None:
|
|
|
362
381
|
_detach_log_handlers(loggers, handlers, prev_levels)
|
|
363
382
|
|
|
364
383
|
_set_subvars(result)
|
|
384
|
+
if opts.get("cleanup"):
|
|
385
|
+
ups.cleanup()
|
|
365
386
|
|
|
366
387
|
if not result.qa_passed:
|
|
367
388
|
raise ErrInfo(
|
|
@@ -399,6 +420,8 @@ def x_pg_upsert_qa(**kwargs: Any) -> None:
|
|
|
399
420
|
|
|
400
421
|
result = _build_result_from_qa_errors(ups)
|
|
401
422
|
_set_subvars(result)
|
|
423
|
+
if opts.get("cleanup"):
|
|
424
|
+
ups.cleanup()
|
|
402
425
|
|
|
403
426
|
if not result.qa_passed:
|
|
404
427
|
raise ErrInfo(
|
|
@@ -439,6 +462,8 @@ def x_pg_upsert_check(**kwargs: Any) -> None:
|
|
|
439
462
|
|
|
440
463
|
result = _build_result_from_qa_errors(ups)
|
|
441
464
|
_set_subvars(result)
|
|
465
|
+
if opts.get("cleanup"):
|
|
466
|
+
ups.cleanup()
|
|
442
467
|
|
|
443
468
|
if not result.qa_passed:
|
|
444
469
|
raise ErrInfo(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: execsql2
|
|
3
|
-
Version: 2.12.
|
|
3
|
+
Version: 2.12.7
|
|
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
|
|
@@ -51,7 +51,7 @@ Requires-Dist: keyring; extra == 'all'
|
|
|
51
51
|
Requires-Dist: odfpy; extra == 'all'
|
|
52
52
|
Requires-Dist: openpyxl; extra == 'all'
|
|
53
53
|
Requires-Dist: oracledb; extra == 'all'
|
|
54
|
-
Requires-Dist: pg-upsert>=1.
|
|
54
|
+
Requires-Dist: pg-upsert>=1.18.2; extra == 'all'
|
|
55
55
|
Requires-Dist: polars; extra == 'all'
|
|
56
56
|
Requires-Dist: psycopg2-binary; extra == 'all'
|
|
57
57
|
Requires-Dist: pymysql; extra == 'all'
|
|
@@ -109,7 +109,7 @@ Requires-Dist: oracledb; extra == 'oracle'
|
|
|
109
109
|
Provides-Extra: postgres
|
|
110
110
|
Requires-Dist: psycopg2-binary; extra == 'postgres'
|
|
111
111
|
Provides-Extra: upsert
|
|
112
|
-
Requires-Dist: pg-upsert>=1.
|
|
112
|
+
Requires-Dist: pg-upsert>=1.18.2; extra == 'upsert'
|
|
113
113
|
Description-Content-Type: text/markdown
|
|
114
114
|
|
|
115
115
|
> [!NOTE]
|
|
@@ -76,7 +76,7 @@ execsql/metacommands/io_write.py,sha256=NpL2aYGfBpbqmPpYsqniYltYfd_SCA1EQz3_4qSd
|
|
|
76
76
|
execsql/metacommands/prompt.py,sha256=xd3mAkdbn4AE4hUPuSfN5DgZGUZmk-Db23iL-JJPwXs,36918
|
|
77
77
|
execsql/metacommands/script_ext.py,sha256=TUgAldB2LSJAwZrCvDDi804hQ1d9BDQD2GDqHNPVOcM,2280
|
|
78
78
|
execsql/metacommands/system.py,sha256=sUR5kLL7idTVg8WXIMdd-Kv7nkERIiaeL0beWsz8NyY,7293
|
|
79
|
-
execsql/metacommands/upsert.py,sha256=
|
|
79
|
+
execsql/metacommands/upsert.py,sha256=P2935aQHDZPiVwnXi0fGQ7Guxrm-Sy_YunyuSqVSegI,15880
|
|
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=6LYabzy1LI-_ISjYzTJos0BrLO62QF6FEKdqcN0YzK4,42995
|
|
@@ -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.12.
|
|
97
|
-
execsql2-2.12.
|
|
98
|
-
execsql2-2.12.
|
|
99
|
-
execsql2-2.12.
|
|
100
|
-
execsql2-2.12.
|
|
101
|
-
execsql2-2.12.
|
|
102
|
-
execsql2-2.12.
|
|
103
|
-
execsql2-2.12.
|
|
104
|
-
execsql2-2.12.
|
|
105
|
-
execsql2-2.12.
|
|
106
|
-
execsql2-2.12.
|
|
107
|
-
execsql2-2.12.
|
|
108
|
-
execsql2-2.12.
|
|
109
|
-
execsql2-2.12.
|
|
110
|
-
execsql2-2.12.
|
|
111
|
-
execsql2-2.12.
|
|
112
|
-
execsql2-2.12.
|
|
113
|
-
execsql2-2.12.
|
|
114
|
-
execsql2-2.12.
|
|
115
|
-
execsql2-2.12.
|
|
116
|
-
execsql2-2.12.
|
|
96
|
+
execsql2-2.12.7.data/data/execsql2_extras/README.md,sha256=sxwVyU0ZahCfANv56LahkyuM505kFjrMhe-1SvWE69E,4845
|
|
97
|
+
execsql2-2.12.7.data/data/execsql2_extras/config_settings.sqlite,sha256=aY5cxR7Q7J6zJ4bC9lu5mHUrhy211Cq3MNKPQVCt02E,20480
|
|
98
|
+
execsql2-2.12.7.data/data/execsql2_extras/example_config_prompt.sql,sha256=SY3Jxn1qcVm4kPW9xmmTfknHfvURXmeEYTbRjYrjGSw,7487
|
|
99
|
+
execsql2-2.12.7.data/data/execsql2_extras/execsql.conf,sha256=_45iJ-KWZnB8uMW_gEg067MM5pmGJ-dVl7VbAZMunAE,9530
|
|
100
|
+
execsql2-2.12.7.data/data/execsql2_extras/make_config_db.sql,sha256=WwyC6dK-Eh5CAVppiBCDHqiI1_wEI9U95Ytpr4lsZkg,8726
|
|
101
|
+
execsql2-2.12.7.data/data/execsql2_extras/md_compare.sql,sha256=B8Wd7LZ0vnMY2qvA139JIEBkPObgRH2i5xj6PejTQt8,24092
|
|
102
|
+
execsql2-2.12.7.data/data/execsql2_extras/md_glossary.sql,sha256=DJRHcU5NbFpxTTX-IwH3yRlsboj1q6BBGrUAHKn4Cuo,10796
|
|
103
|
+
execsql2-2.12.7.data/data/execsql2_extras/md_upsert.sql,sha256=v_7GbWh_N1mBTmw3gvTrkagOVp2q0KmXvM8hE-DlFxY,112524
|
|
104
|
+
execsql2-2.12.7.data/data/execsql2_extras/pg_compare.sql,sha256=9dWa8hnfy5dVJI-z2iGpd9JzQmI4j2ziMlEdpnr66ro,24352
|
|
105
|
+
execsql2-2.12.7.data/data/execsql2_extras/pg_glossary.sql,sha256=pKjIIDsROAgJq2H-1qNEcRMAWManivcZ_AEVHzUUlic,9908
|
|
106
|
+
execsql2-2.12.7.data/data/execsql2_extras/pg_upsert.sql,sha256=k7AFiGTLBy3nf-qO5QIaZrEYTAKvdxxU3JDLx9jqkzs,108315
|
|
107
|
+
execsql2-2.12.7.data/data/execsql2_extras/script_template.sql,sha256=1Estacb_vm1FgK41k_G9nuduP1yiA-fQ1Kn4Z4mv5Ao,11153
|
|
108
|
+
execsql2-2.12.7.data/data/execsql2_extras/ss_compare.sql,sha256=TsVxWm3cEpR5-EiMYXNhtaY0arSNeKZhsJdHdLA7xeI,24833
|
|
109
|
+
execsql2-2.12.7.data/data/execsql2_extras/ss_glossary.sql,sha256=cLM7nN8JOIu9ZVP9oY9qdSK3hrnWJiDcX6nZmQQbQWI,13065
|
|
110
|
+
execsql2-2.12.7.data/data/execsql2_extras/ss_upsert.sql,sha256=BCqmBykXBF-BpCgOFeG1qhf2XfScKsxPD17wd1hYfHw,120647
|
|
111
|
+
execsql2-2.12.7.dist-info/METADATA,sha256=lTHj9-vwr6EtjnWXy6enLyg8ZRxJLXHbsRbYIPjtazg,17560
|
|
112
|
+
execsql2-2.12.7.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
113
|
+
execsql2-2.12.7.dist-info/entry_points.txt,sha256=sUOxkM-dN1eBGGpSpDLsAaE0yNXYQKWZAfxPOlMkQyk,90
|
|
114
|
+
execsql2-2.12.7.dist-info/licenses/LICENSE.txt,sha256=LBdhuxejF8_bLCHZ2kWfmDXpDGUu914Gbd6_3JjCRe0,676
|
|
115
|
+
execsql2-2.12.7.dist-info/licenses/NOTICE,sha256=sqVrM73Ys9zfvWC_P797lHfTnoPW_ETeBSrUTFaob0A,339
|
|
116
|
+
execsql2-2.12.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
{execsql2-2.12.5.data → execsql2-2.12.7.data}/data/execsql2_extras/example_config_prompt.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|