execsql2 2.1.2__py3-none-any.whl → 2.4.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.
- execsql/cli/__init__.py +436 -0
- execsql/cli/dsn.py +86 -0
- execsql/cli/help.py +140 -0
- execsql/{cli.py → cli/run.py} +14 -589
- execsql/config.py +65 -1
- execsql/db/access.py +27 -15
- execsql/db/base.py +328 -215
- execsql/db/dsn.py +10 -5
- execsql/db/duckdb.py +6 -2
- execsql/db/factory.py +21 -0
- execsql/db/firebird.py +27 -19
- execsql/db/mysql.py +12 -7
- execsql/db/oracle.py +15 -11
- execsql/db/postgres.py +31 -16
- execsql/db/sqlite.py +15 -11
- execsql/db/sqlserver.py +16 -5
- execsql/exceptions.py +25 -7
- execsql/exporters/base.py +12 -1
- execsql/exporters/delimited.py +80 -35
- execsql/exporters/duckdb.py +6 -2
- execsql/exporters/feather.py +10 -6
- execsql/exporters/html.py +89 -69
- execsql/exporters/json.py +52 -45
- execsql/exporters/latex.py +37 -27
- execsql/exporters/ods.py +32 -11
- execsql/exporters/parquet.py +5 -2
- execsql/exporters/pretty.py +16 -9
- execsql/exporters/raw.py +22 -16
- execsql/exporters/sqlite.py +6 -2
- execsql/exporters/templates.py +39 -21
- execsql/exporters/values.py +26 -20
- execsql/exporters/xls.py +30 -11
- execsql/exporters/xml.py +31 -13
- execsql/exporters/zip.py +15 -0
- execsql/importers/base.py +6 -4
- execsql/importers/csv.py +8 -6
- execsql/importers/feather.py +6 -4
- execsql/importers/ods.py +6 -4
- execsql/importers/xls.py +6 -4
- execsql/metacommands/__init__.py +208 -1548
- execsql/metacommands/conditions.py +101 -27
- execsql/metacommands/control.py +8 -4
- execsql/metacommands/data.py +6 -6
- execsql/metacommands/debug.py +6 -2
- execsql/metacommands/dispatch.py +2011 -0
- execsql/metacommands/io.py +67 -1310
- execsql/metacommands/io_export.py +442 -0
- execsql/metacommands/io_fileops.py +287 -0
- execsql/metacommands/io_import.py +398 -0
- execsql/metacommands/io_write.py +248 -0
- execsql/metacommands/prompt.py +22 -66
- execsql/metacommands/system.py +7 -2
- execsql/models.py +7 -0
- execsql/parser.py +10 -0
- execsql/py.typed +0 -0
- execsql/script/__init__.py +95 -0
- execsql/script/control.py +162 -0
- execsql/{script.py → script/engine.py} +184 -402
- execsql/script/variables.py +281 -0
- execsql/types.py +49 -20
- execsql/utils/auth.py +2 -0
- execsql/utils/crypto.py +4 -6
- execsql/utils/datetime.py +1 -0
- execsql/utils/errors.py +11 -0
- execsql/utils/fileio.py +33 -8
- execsql/utils/gui.py +46 -0
- execsql/utils/mail.py +7 -17
- execsql/utils/numeric.py +2 -0
- execsql/utils/regex.py +9 -0
- execsql/utils/strings.py +16 -0
- execsql/utils/timer.py +2 -0
- execsql2-2.4.0.data/data/execsql2_extras/README.md +65 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/execsql.conf +1 -1
- {execsql2-2.1.2.dist-info → execsql2-2.4.0.dist-info}/METADATA +13 -6
- execsql2-2.4.0.dist-info/RECORD +108 -0
- execsql2-2.1.2.data/data/execsql2_extras/READ_ME.rst +0 -127
- execsql2-2.1.2.dist-info/RECORD +0 -96
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/config_settings.sqlite +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/make_config_db.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/md_compare.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/md_glossary.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/md_upsert.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/pg_compare.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/pg_glossary.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/pg_upsert.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/script_template.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/ss_compare.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/ss_glossary.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/ss_upsert.sql +0 -0
- {execsql2-2.1.2.dist-info → execsql2-2.4.0.dist-info}/WHEEL +0 -0
- {execsql2-2.1.2.dist-info → execsql2-2.4.0.dist-info}/entry_points.txt +0 -0
- {execsql2-2.1.2.dist-info → execsql2-2.4.0.dist-info}/licenses/LICENSE.txt +0 -0
- {execsql2-2.1.2.dist-info → execsql2-2.4.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
"""Export metacommand handlers.
|
|
2
|
+
|
|
3
|
+
Implements ``x_export``, ``x_export_query``, template-based exports,
|
|
4
|
+
ODS multi-sheet export, and export metadata operations.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
import execsql.state as _state
|
|
13
|
+
from execsql.exceptions import ErrInfo
|
|
14
|
+
from execsql.exporters.base import ExportRecord
|
|
15
|
+
from execsql.exporters.delimited import write_delimited_file
|
|
16
|
+
from execsql.exporters.duckdb import write_query_to_duckdb
|
|
17
|
+
from execsql.exporters.feather import write_query_to_feather, write_query_to_hdf5
|
|
18
|
+
from execsql.exporters.html import write_query_to_cgi_html, write_query_to_html
|
|
19
|
+
from execsql.exporters.json import write_query_to_json, write_query_to_json_ts
|
|
20
|
+
from execsql.exporters.latex import write_query_to_latex
|
|
21
|
+
from execsql.exporters.ods import write_queries_to_ods, write_query_to_ods
|
|
22
|
+
from execsql.exporters.parquet import write_query_to_parquet
|
|
23
|
+
from execsql.exporters.pretty import prettyprint_query, prettyprint_rowset
|
|
24
|
+
from execsql.exporters.raw import write_query_b64, write_query_raw
|
|
25
|
+
from execsql.exporters.sqlite import write_query_to_sqlite
|
|
26
|
+
from execsql.exporters.templates import report_query
|
|
27
|
+
from execsql.exporters.values import write_query_to_values
|
|
28
|
+
from execsql.exporters.xml import write_query_to_xml
|
|
29
|
+
from execsql.importers.base import import_data_table
|
|
30
|
+
from execsql.script import current_script_line
|
|
31
|
+
from execsql.utils.errors import exception_desc
|
|
32
|
+
from execsql.utils.fileio import check_dir
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _apply_output_dir(path: str) -> str:
|
|
36
|
+
"""Prepend the configured --output-dir to *path* if it is a relative path.
|
|
37
|
+
|
|
38
|
+
If ``conf.export_output_dir`` is set and *path* is not absolute (and not
|
|
39
|
+
``stdout``), the base directory is joined to *path* so that all EXPORT
|
|
40
|
+
output lands in the same directory without requiring scripts to hard-code
|
|
41
|
+
absolute paths.
|
|
42
|
+
"""
|
|
43
|
+
output_dir = getattr(_state.conf, "export_output_dir", None)
|
|
44
|
+
if not output_dir:
|
|
45
|
+
return path
|
|
46
|
+
if path.lower() == "stdout":
|
|
47
|
+
return path
|
|
48
|
+
if Path(path).is_absolute():
|
|
49
|
+
return path
|
|
50
|
+
# Windows drive-letter paths are also absolute
|
|
51
|
+
if len(path) > 1 and path[1] == ":":
|
|
52
|
+
return path
|
|
53
|
+
return str(Path(output_dir) / path)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def x_export(**kwargs: Any) -> None:
|
|
57
|
+
schema = kwargs["schema"]
|
|
58
|
+
table = kwargs["table"]
|
|
59
|
+
queryname = _state.dbs.current().schema_qualified_table_name(schema, table)
|
|
60
|
+
select_stmt = f"select * from {queryname};"
|
|
61
|
+
outfile = _apply_output_dir(kwargs["filename"])
|
|
62
|
+
description = kwargs["description"]
|
|
63
|
+
tee = kwargs["tee"]
|
|
64
|
+
tee = bool(tee)
|
|
65
|
+
append = kwargs["append"]
|
|
66
|
+
append = bool(append)
|
|
67
|
+
filefmt = kwargs["format"].lower()
|
|
68
|
+
zipfilename = _apply_output_dir(kwargs["zipfilename"]) if kwargs["zipfilename"] else None
|
|
69
|
+
if zipfilename is not None:
|
|
70
|
+
if outfile.lower() == "stdout":
|
|
71
|
+
raise ErrInfo("error", other_msg="Cannot write stdout to a zipfile.")
|
|
72
|
+
elif len(outfile) > 1 and outfile[1] == ":":
|
|
73
|
+
raise ErrInfo("error", other_msg="Cannot use a drive letter for a file path within a zipfile.")
|
|
74
|
+
if filefmt == "duckdb":
|
|
75
|
+
raise ErrInfo("error", other_msg="Cannot export to the DuckDB format within a zipfile.")
|
|
76
|
+
if filefmt == "sqlite":
|
|
77
|
+
raise ErrInfo("error", other_msg="Cannot export to the SQLite format within a zipfile.")
|
|
78
|
+
if filefmt == "latex":
|
|
79
|
+
raise ErrInfo("error", other_msg="Cannot export to the LaTeX format within a zipfile.")
|
|
80
|
+
if filefmt == "feather":
|
|
81
|
+
raise ErrInfo("error", other_msg="Cannot export to the feather format within a zipfile.")
|
|
82
|
+
if filefmt == "parquet":
|
|
83
|
+
raise ErrInfo("error", other_msg="Cannot export to the parquet format within a zipfile.")
|
|
84
|
+
if filefmt == "hdf5":
|
|
85
|
+
raise ErrInfo("error", other_msg="Cannot export to the HDF5 format within a zipfile.")
|
|
86
|
+
if filefmt == "ods":
|
|
87
|
+
raise ErrInfo("error", other_msg="Cannot export to an ODS workbook within a zipfile.")
|
|
88
|
+
notype = bool(kwargs.get("notype"))
|
|
89
|
+
if zipfilename is not None:
|
|
90
|
+
check_dir(zipfilename)
|
|
91
|
+
else:
|
|
92
|
+
check_dir(outfile)
|
|
93
|
+
if tee and outfile.lower() != "stdout":
|
|
94
|
+
prettyprint_query(select_stmt, _state.dbs.current(), "stdout", False, desc=description)
|
|
95
|
+
if filefmt in ("txt", "text"):
|
|
96
|
+
prettyprint_query(
|
|
97
|
+
select_stmt,
|
|
98
|
+
_state.dbs.current(),
|
|
99
|
+
outfile,
|
|
100
|
+
append,
|
|
101
|
+
desc=description,
|
|
102
|
+
zipfile=zipfilename,
|
|
103
|
+
)
|
|
104
|
+
elif filefmt in ("txt-and", "text-and", "txt-and", "text-and"):
|
|
105
|
+
prettyprint_query(
|
|
106
|
+
select_stmt,
|
|
107
|
+
_state.dbs.current(),
|
|
108
|
+
outfile,
|
|
109
|
+
append,
|
|
110
|
+
and_val="AND",
|
|
111
|
+
desc=description,
|
|
112
|
+
zipfile=zipfilename,
|
|
113
|
+
)
|
|
114
|
+
elif filefmt == "ods":
|
|
115
|
+
write_query_to_ods(
|
|
116
|
+
select_stmt,
|
|
117
|
+
_state.dbs.current(),
|
|
118
|
+
outfile,
|
|
119
|
+
append,
|
|
120
|
+
sheetname=queryname,
|
|
121
|
+
desc=description,
|
|
122
|
+
)
|
|
123
|
+
elif filefmt == "duckdb":
|
|
124
|
+
write_query_to_duckdb(select_stmt, _state.dbs.current(), outfile, append, tablename=queryname)
|
|
125
|
+
elif filefmt == "sqlite":
|
|
126
|
+
write_query_to_sqlite(select_stmt, _state.dbs.current(), outfile, append, tablename=queryname)
|
|
127
|
+
elif filefmt == "xml":
|
|
128
|
+
write_query_to_xml(
|
|
129
|
+
select_stmt,
|
|
130
|
+
table,
|
|
131
|
+
_state.dbs.current(),
|
|
132
|
+
outfile,
|
|
133
|
+
append,
|
|
134
|
+
desc=description,
|
|
135
|
+
zipfile=zipfilename,
|
|
136
|
+
)
|
|
137
|
+
elif filefmt == "json":
|
|
138
|
+
write_query_to_json(
|
|
139
|
+
select_stmt,
|
|
140
|
+
_state.dbs.current(),
|
|
141
|
+
outfile,
|
|
142
|
+
append,
|
|
143
|
+
desc=description,
|
|
144
|
+
zipfile=zipfilename,
|
|
145
|
+
)
|
|
146
|
+
elif filefmt in ("json_ts", "json_tableschema"):
|
|
147
|
+
write_query_to_json_ts(
|
|
148
|
+
select_stmt,
|
|
149
|
+
_state.dbs.current(),
|
|
150
|
+
outfile,
|
|
151
|
+
append,
|
|
152
|
+
not notype,
|
|
153
|
+
desc=description,
|
|
154
|
+
zipfile=zipfilename,
|
|
155
|
+
)
|
|
156
|
+
elif filefmt == "values":
|
|
157
|
+
write_query_to_values(
|
|
158
|
+
select_stmt,
|
|
159
|
+
_state.dbs.current(),
|
|
160
|
+
outfile,
|
|
161
|
+
append,
|
|
162
|
+
desc=description,
|
|
163
|
+
zipfile=zipfilename,
|
|
164
|
+
)
|
|
165
|
+
elif filefmt == "html":
|
|
166
|
+
write_query_to_html(
|
|
167
|
+
select_stmt,
|
|
168
|
+
_state.dbs.current(),
|
|
169
|
+
outfile,
|
|
170
|
+
append,
|
|
171
|
+
desc=description,
|
|
172
|
+
zipfile=zipfilename,
|
|
173
|
+
)
|
|
174
|
+
elif filefmt == "cgi-html":
|
|
175
|
+
write_query_to_cgi_html(
|
|
176
|
+
select_stmt,
|
|
177
|
+
_state.dbs.current(),
|
|
178
|
+
outfile,
|
|
179
|
+
append,
|
|
180
|
+
desc=description,
|
|
181
|
+
zipfile=zipfilename,
|
|
182
|
+
)
|
|
183
|
+
elif filefmt == "latex":
|
|
184
|
+
write_query_to_latex(
|
|
185
|
+
select_stmt,
|
|
186
|
+
_state.dbs.current(),
|
|
187
|
+
outfile,
|
|
188
|
+
append,
|
|
189
|
+
desc=description,
|
|
190
|
+
zipfile=zipfilename,
|
|
191
|
+
)
|
|
192
|
+
elif filefmt == "hdf5":
|
|
193
|
+
write_query_to_hdf5(table, select_stmt, _state.dbs.current(), outfile, append, desc=description)
|
|
194
|
+
else:
|
|
195
|
+
try:
|
|
196
|
+
hdrs, rows = _state.dbs.current().select_rowsource(select_stmt)
|
|
197
|
+
except ErrInfo:
|
|
198
|
+
raise
|
|
199
|
+
except Exception as e:
|
|
200
|
+
raise ErrInfo("db", select_stmt, exception_msg=exception_desc()) from e
|
|
201
|
+
if filefmt == "raw":
|
|
202
|
+
write_query_raw(outfile, rows, _state.dbs.current().encoding, append, zipfile=zipfilename)
|
|
203
|
+
elif filefmt == "b64":
|
|
204
|
+
write_query_b64(outfile, rows, append)
|
|
205
|
+
elif filefmt == "feather":
|
|
206
|
+
write_query_to_feather(outfile, hdrs, rows)
|
|
207
|
+
elif filefmt == "parquet":
|
|
208
|
+
write_query_to_parquet(outfile, hdrs, rows)
|
|
209
|
+
else:
|
|
210
|
+
write_delimited_file(outfile, filefmt, hdrs, rows, _state.conf.output_encoding, append, zipfilename)
|
|
211
|
+
_state.export_metadata.add(ExportRecord(queryname, outfile, zipfilename, description))
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def x_export_query(**kwargs: Any) -> None:
|
|
216
|
+
select_stmt = kwargs["query"]
|
|
217
|
+
outfile = kwargs["filename"]
|
|
218
|
+
description = kwargs["description"]
|
|
219
|
+
tee = kwargs["tee"]
|
|
220
|
+
tee = bool(tee)
|
|
221
|
+
append = kwargs["append"]
|
|
222
|
+
append = bool(append)
|
|
223
|
+
filefmt = kwargs["format"].lower()
|
|
224
|
+
zipfilename = kwargs["zipfilename"]
|
|
225
|
+
if zipfilename is not None:
|
|
226
|
+
if outfile == "stdout":
|
|
227
|
+
raise ErrInfo("error", other_msg="Cannot write stdout to a zipfile.")
|
|
228
|
+
elif len(outfile) > 1 and outfile[1] == ":":
|
|
229
|
+
raise ErrInfo("error", other_msg="Cannot use a drive letter for a file path within a zipfile.")
|
|
230
|
+
if filefmt == "latex":
|
|
231
|
+
raise ErrInfo("error", other_msg="Cannot export to the LaTeX format within a zipfile.")
|
|
232
|
+
if filefmt == "feather":
|
|
233
|
+
raise ErrInfo("error", other_msg="Cannot export to the feather format within a zipfile.")
|
|
234
|
+
if filefmt == "parquet":
|
|
235
|
+
raise ErrInfo("error", other_msg="Cannot export to the parquet format within a zipfile.")
|
|
236
|
+
if filefmt == "hdf5":
|
|
237
|
+
raise ErrInfo("error", other_msg="Cannot export to the HDF5 format within a zipfile.")
|
|
238
|
+
if filefmt == "ods":
|
|
239
|
+
raise ErrInfo("error", other_msg="Cannot export to an ODS workbook within a zipfile.")
|
|
240
|
+
notype = bool(kwargs.get("notype"))
|
|
241
|
+
check_dir(outfile)
|
|
242
|
+
if tee and outfile.lower() != "stdout":
|
|
243
|
+
prettyprint_query(select_stmt, _state.dbs.current(), "stdout", False, desc=description)
|
|
244
|
+
if filefmt in ("txt", "text"):
|
|
245
|
+
prettyprint_query(
|
|
246
|
+
select_stmt,
|
|
247
|
+
_state.dbs.current(),
|
|
248
|
+
outfile,
|
|
249
|
+
append,
|
|
250
|
+
desc=description,
|
|
251
|
+
zipfile=zipfilename,
|
|
252
|
+
)
|
|
253
|
+
elif filefmt in ("txt-and", "text-and", "txt-and", "text-and"):
|
|
254
|
+
prettyprint_query(
|
|
255
|
+
select_stmt,
|
|
256
|
+
_state.dbs.current(),
|
|
257
|
+
outfile,
|
|
258
|
+
append,
|
|
259
|
+
and_val="AND",
|
|
260
|
+
desc=description,
|
|
261
|
+
zipfile=zipfilename,
|
|
262
|
+
)
|
|
263
|
+
elif filefmt == "ods":
|
|
264
|
+
script_name, lno = current_script_line()
|
|
265
|
+
write_query_to_ods(
|
|
266
|
+
select_stmt,
|
|
267
|
+
_state.dbs.current(),
|
|
268
|
+
outfile,
|
|
269
|
+
append,
|
|
270
|
+
sheetname=f"Query_{lno}",
|
|
271
|
+
desc=description,
|
|
272
|
+
)
|
|
273
|
+
elif filefmt == "json":
|
|
274
|
+
write_query_to_json(
|
|
275
|
+
select_stmt,
|
|
276
|
+
_state.dbs.current(),
|
|
277
|
+
outfile,
|
|
278
|
+
append,
|
|
279
|
+
desc=description,
|
|
280
|
+
zipfile=zipfilename,
|
|
281
|
+
)
|
|
282
|
+
elif filefmt in ("json_ts", "json_tableschema"):
|
|
283
|
+
write_query_to_json_ts(
|
|
284
|
+
select_stmt,
|
|
285
|
+
_state.dbs.current(),
|
|
286
|
+
outfile,
|
|
287
|
+
append,
|
|
288
|
+
not notype,
|
|
289
|
+
desc=description,
|
|
290
|
+
zipfile=zipfilename,
|
|
291
|
+
)
|
|
292
|
+
elif filefmt == "values":
|
|
293
|
+
write_query_to_values(
|
|
294
|
+
select_stmt,
|
|
295
|
+
_state.dbs.current(),
|
|
296
|
+
outfile,
|
|
297
|
+
append,
|
|
298
|
+
desc=description,
|
|
299
|
+
zipfile=zipfilename,
|
|
300
|
+
)
|
|
301
|
+
elif filefmt == "html":
|
|
302
|
+
write_query_to_html(
|
|
303
|
+
select_stmt,
|
|
304
|
+
_state.dbs.current(),
|
|
305
|
+
outfile,
|
|
306
|
+
append,
|
|
307
|
+
desc=description,
|
|
308
|
+
zipfile=zipfilename,
|
|
309
|
+
)
|
|
310
|
+
elif filefmt == "cgi-html":
|
|
311
|
+
write_query_to_cgi_html(
|
|
312
|
+
select_stmt,
|
|
313
|
+
_state.dbs.current(),
|
|
314
|
+
outfile,
|
|
315
|
+
append,
|
|
316
|
+
desc=description,
|
|
317
|
+
zipfile=zipfilename,
|
|
318
|
+
)
|
|
319
|
+
elif filefmt == "latex":
|
|
320
|
+
write_query_to_latex(
|
|
321
|
+
select_stmt,
|
|
322
|
+
_state.dbs.current(),
|
|
323
|
+
outfile,
|
|
324
|
+
append,
|
|
325
|
+
desc=description,
|
|
326
|
+
zipfile=zipfilename,
|
|
327
|
+
)
|
|
328
|
+
else:
|
|
329
|
+
try:
|
|
330
|
+
hdrs, rows = _state.dbs.current().select_rowsource(select_stmt)
|
|
331
|
+
except ErrInfo:
|
|
332
|
+
raise
|
|
333
|
+
except Exception as e:
|
|
334
|
+
raise ErrInfo("db", select_stmt, exception_msg=exception_desc()) from e
|
|
335
|
+
if filefmt == "raw":
|
|
336
|
+
write_query_raw(outfile, rows, _state.dbs.current().encoding, append, zipfile=zipfilename)
|
|
337
|
+
elif filefmt == "b64":
|
|
338
|
+
write_query_b64(outfile, rows, append, zipfile=zipfilename)
|
|
339
|
+
elif filefmt == "feather":
|
|
340
|
+
write_query_to_feather(outfile, hdrs, rows)
|
|
341
|
+
elif filefmt == "parquet":
|
|
342
|
+
write_query_to_parquet(outfile, hdrs, rows)
|
|
343
|
+
else:
|
|
344
|
+
write_delimited_file(
|
|
345
|
+
outfile,
|
|
346
|
+
filefmt,
|
|
347
|
+
hdrs,
|
|
348
|
+
rows,
|
|
349
|
+
_state.conf.output_encoding,
|
|
350
|
+
append,
|
|
351
|
+
zipfile=zipfilename,
|
|
352
|
+
)
|
|
353
|
+
_state.export_metadata.add(ExportRecord(select_stmt, outfile, zipfilename, description))
|
|
354
|
+
return None
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def x_export_query_with_template(**kwargs: Any) -> None:
|
|
358
|
+
select_stmt = kwargs["query"]
|
|
359
|
+
outfile = kwargs["filename"]
|
|
360
|
+
template_file = kwargs["template"]
|
|
361
|
+
tee = kwargs["tee"]
|
|
362
|
+
tee = bool(tee)
|
|
363
|
+
append = kwargs["append"]
|
|
364
|
+
append = bool(append)
|
|
365
|
+
zipfilename = kwargs["zipfilename"]
|
|
366
|
+
check_dir(outfile)
|
|
367
|
+
if tee and outfile.lower() != "stdout":
|
|
368
|
+
prettyprint_query(select_stmt, _state.dbs.current(), "stdout", False)
|
|
369
|
+
report_query(select_stmt, _state.dbs.current(), outfile, template_file, append, zipfile=zipfilename)
|
|
370
|
+
_state.export_metadata.add(ExportRecord(select_stmt, outfile, zipfilename))
|
|
371
|
+
return None
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
def x_export_with_template(**kwargs: Any) -> None:
|
|
375
|
+
schema = kwargs["schema"]
|
|
376
|
+
table = kwargs["table"]
|
|
377
|
+
queryname = _state.dbs.current().schema_qualified_table_name(schema, table)
|
|
378
|
+
select_stmt = f"select * from {queryname};"
|
|
379
|
+
outfile = kwargs["filename"]
|
|
380
|
+
template_file = kwargs["template"]
|
|
381
|
+
tee = kwargs["tee"]
|
|
382
|
+
tee = bool(tee)
|
|
383
|
+
append = kwargs["append"]
|
|
384
|
+
append = bool(append)
|
|
385
|
+
zipfilename = kwargs["zipfilename"]
|
|
386
|
+
check_dir(outfile)
|
|
387
|
+
if tee and outfile.lower() != "stdout":
|
|
388
|
+
prettyprint_query(select_stmt, _state.dbs.current(), "stdout", False)
|
|
389
|
+
report_query(select_stmt, _state.dbs.current(), outfile, template_file, append, zipfile=zipfilename)
|
|
390
|
+
_state.export_metadata.add(ExportRecord(queryname, outfile, zipfilename))
|
|
391
|
+
return None
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
def x_export_ods_multiple(**kwargs: Any) -> None:
|
|
395
|
+
table_list = kwargs["tables"]
|
|
396
|
+
outfile = kwargs["filename"]
|
|
397
|
+
description = kwargs["description"]
|
|
398
|
+
tee = kwargs["tee"]
|
|
399
|
+
tee = bool(tee)
|
|
400
|
+
append = kwargs["append"]
|
|
401
|
+
append = append is not None
|
|
402
|
+
check_dir(outfile)
|
|
403
|
+
write_queries_to_ods(table_list, _state.dbs.current(), outfile, append, tee, desc=description)
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def x_export_metadata(**kwargs: Any) -> None:
|
|
407
|
+
outfile = kwargs["filename"]
|
|
408
|
+
append = kwargs["append"] is not None
|
|
409
|
+
xall = kwargs["all"] is not None
|
|
410
|
+
zipfilename = kwargs["zipfilename"]
|
|
411
|
+
filefmt = kwargs["format"].lower()
|
|
412
|
+
if xall:
|
|
413
|
+
hdrs, rows = _state.export_metadata.get_all()
|
|
414
|
+
else:
|
|
415
|
+
hdrs, rows = _state.export_metadata.get()
|
|
416
|
+
if outfile.lower() != "stdout":
|
|
417
|
+
check_dir(outfile)
|
|
418
|
+
if filefmt in ("txt", "text"):
|
|
419
|
+
prettyprint_rowset(hdrs, rows, outfile, append, and_val="", zipfile=zipfilename)
|
|
420
|
+
else:
|
|
421
|
+
write_delimited_file(outfile, filefmt, hdrs, rows, _state.conf.output_encoding, append, zipfilename)
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
def x_export_metadata_table(**kwargs: Any) -> None:
|
|
425
|
+
xall = kwargs["all"] is not None
|
|
426
|
+
schemaname = kwargs["schema"]
|
|
427
|
+
tablename = kwargs["table"]
|
|
428
|
+
newstr = kwargs["new"]
|
|
429
|
+
if newstr:
|
|
430
|
+
is_new = 1 + ["new", "replacement"].index(newstr.lower())
|
|
431
|
+
else:
|
|
432
|
+
is_new = 0
|
|
433
|
+
if xall:
|
|
434
|
+
hdrs, rows = _state.export_metadata.get_all()
|
|
435
|
+
else:
|
|
436
|
+
hdrs, rows = _state.export_metadata.get()
|
|
437
|
+
import_data_table(_state.dbs.current(), schemaname, tablename, is_new, hdrs, rows)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def x_export_row_buffer(**kwargs: Any) -> None:
|
|
441
|
+
rows = kwargs["rows"]
|
|
442
|
+
_state.conf.export_row_buffer = int(rows)
|