Skip to content

Commit b8bcf7a

Browse files
committed
feat(sql2csv): Add --execution-option option, use stream_results=True by default, closes #1255
1 parent 2fab831 commit b8bcf7a

17 files changed

+51
-16
lines changed

CHANGELOG.rst

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Unreleased
2+
----------
3+
4+
- feat: :doc:`/scripts/sql2csv` adds a :code:`--execution-option` option.
5+
- feat: :doc:`/scripts/sql2csv` uses the ``stream_results=True`` execution option, by default, to not load all data into memory at once.
6+
17
2.0.1 - July 12, 2024
28
---------------------
39

csvkit/utilities/sql2csv.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
#!/usr/bin/env python
2+
import ast
23

34
import agate
45
from sqlalchemy import create_engine
56

67
from csvkit.cli import CSVKitUtility
78

89

10+
def parse_list(pairs):
11+
options = {}
12+
for key, value in pairs:
13+
try:
14+
value = ast.literal_eval(value)
15+
except ValueError:
16+
pass
17+
options[key] = value
18+
return options
19+
20+
921
class SQL2CSV(CSVKitUtility):
1022
description = 'Execute a SQL query on a database and output the result to a CSV file.'
1123
# Overrides all flags except --linenumbers, --verbose, --version.
@@ -19,6 +31,13 @@ def add_arguments(self):
1931
'--engine-option', dest='engine_option', nargs=2, action='append', default=[],
2032
help="A keyword argument to SQLAlchemy's create_engine(), as a space-separated pair. "
2133
"This option can be specified multiple times. For example: thick_mode True")
34+
self.argparser.add_argument(
35+
'--execution-option', dest='execution_option', nargs=2, action='append',
36+
# https://docs.sqlalchemy.org/en/20/core/connections.html#sqlalchemy.engine.Connection.execution_options.params.no_parameters
37+
# https://docs.sqlalchemy.org/en/20/core/connections.html#sqlalchemy.engine.Connection.execution_options.params.stream_results
38+
default=[['no_parameters', True], ['stream_results', True]],
39+
help="A keyword argument to SQLAlchemy's execution_options(), as a space-separated pair. "
40+
"This option can be specified multiple times. For example: stream_results True")
2241
self.argparser.add_argument(
2342
metavar='FILE', nargs='?', dest='input_path',
2443
help='The file to use as SQL query. If FILE and --query are omitted, the query is piped data via STDIN.')
@@ -49,7 +68,7 @@ def main(self):
4968
self.argparser.error('You must provide an input file or piped data.')
5069

5170
try:
52-
engine = create_engine(self.args.connection_string, **dict(self.args.engine_option))
71+
engine = create_engine(self.args.connection_string, **parse_list(self.args.engine_option))
5372
except ImportError as e:
5473
raise ImportError(
5574
"You don't appear to have the necessary database backend installed for connection string you're "
@@ -73,7 +92,7 @@ def main(self):
7392

7493
self.input_file.close()
7594

76-
rows = connection.execution_options(no_parameters=True).exec_driver_sql(query)
95+
rows = connection.execution_options(**parse_list(self.args.execution_option)).exec_driver_sql(query)
7796
output = agate.csv.writer(self.output_file, **self.writer_kwargs)
7897

7998
if rows.returns_rows:

docs/scripts/sql2csv.rst

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ Executes arbitrary commands against a SQL database and outputs the results as a
2828
A keyword argument to SQLAlchemy's create_engine(), as
2929
a space-separated pair. This option can be specified
3030
multiple times. For example: thick_mode True
31+
--execution-option EXECUTION_OPTION EXECUTION_OPTION
32+
A keyword argument to SQLAlchemy's
33+
execution_options(), as a space-separated pair. This
34+
option can be specified multiple times. For example:
35+
stream_results True
3136
--query QUERY The SQL query to execute. Overrides FILE and STDIN.
3237
-e ENCODING, --encoding ENCODING
3338
Specify the encoding of the input query file.

man/csvclean.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVCLEAN" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVCLEAN" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvclean \- csvclean Documentation
3333
.SH DESCRIPTION

man/csvcut.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVCUT" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVCUT" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvcut \- csvcut Documentation
3333
.SH DESCRIPTION

man/csvformat.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVFORMAT" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVFORMAT" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvformat \- csvformat Documentation
3333
.SH DESCRIPTION

man/csvgrep.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVGREP" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVGREP" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvgrep \- csvgrep Documentation
3333
.SH DESCRIPTION

man/csvjoin.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVJOIN" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVJOIN" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvjoin \- csvjoin Documentation
3333
.SH DESCRIPTION

man/csvjson.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVJSON" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVJSON" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvjson \- csvjson Documentation
3333
.SH DESCRIPTION

man/csvlook.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVLOOK" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVLOOK" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvlook \- csvlook Documentation
3333
.SH DESCRIPTION

man/csvpy.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVPY" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVPY" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvpy \- csvpy Documentation
3333
.SH DESCRIPTION

man/csvsort.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVSORT" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVSORT" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvsort \- csvsort Documentation
3333
.SH DESCRIPTION

man/csvsql.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVSQL" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVSQL" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvsql \- csvsql Documentation
3333
.SH DESCRIPTION

man/csvstack.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVSTACK" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVSTACK" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvstack \- csvstack Documentation
3333
.SH DESCRIPTION

man/csvstat.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "CSVSTAT" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "CSVSTAT" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
csvstat \- csvstat Documentation
3333
.SH DESCRIPTION

man/in2csv.1

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "IN2CSV" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "IN2CSV" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
in2csv \- in2csv Documentation
3333
.SH DESCRIPTION

man/sql2csv.1

+6-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
2727
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
2828
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
2929
..
30-
.TH "SQL2CSV" "1" "Jul 12, 2024" "2.0.1" "csvkit"
30+
.TH "SQL2CSV" "1" "Jul 16, 2024" "2.0.1" "csvkit"
3131
.SH NAME
3232
sql2csv \- sql2csv Documentation
3333
.SH DESCRIPTION
@@ -57,6 +57,11 @@ optional arguments:
5757
A keyword argument to SQLAlchemy\(aqs create_engine(), as
5858
a space\-separated pair. This option can be specified
5959
multiple times. For example: thick_mode True
60+
\-\-execution\-option EXECUTION_OPTION EXECUTION_OPTION
61+
A keyword argument to SQLAlchemy\(aqs
62+
execution_options(), as a space\-separated pair. This
63+
option can be specified multiple times. For example:
64+
stream_results True
6065
\-\-query QUERY The SQL query to execute. Overrides FILE and STDIN.
6166
\-e ENCODING, \-\-encoding ENCODING
6267
Specify the encoding of the input query file.

0 commit comments

Comments
 (0)