sql2csv 1.4__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.
- sql2csv/__init__.py +0 -0
- sql2csv/__main__.py +4 -0
- sql2csv/sql2csv.py +340 -0
- sql2csv-1.4.dist-info/METADATA +144 -0
- sql2csv-1.4.dist-info/RECORD +9 -0
- sql2csv-1.4.dist-info/WHEEL +5 -0
- sql2csv-1.4.dist-info/entry_points.txt +2 -0
- sql2csv-1.4.dist-info/licenses/LICENSE +21 -0
- sql2csv-1.4.dist-info/top_level.txt +1 -0
sql2csv/__init__.py
ADDED
|
File without changes
|
sql2csv/__main__.py
ADDED
sql2csv/sql2csv.py
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import csv
|
|
5
|
+
import tempfile
|
|
6
|
+
import os
|
|
7
|
+
from os.path import expanduser
|
|
8
|
+
import json
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import pymysql.cursors
|
|
12
|
+
import pymysql.constants.CLIENT
|
|
13
|
+
import psycopg2.extras
|
|
14
|
+
import psycopg2
|
|
15
|
+
|
|
16
|
+
file_ = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_mysql_connection(host, user, port, password, database):
|
|
20
|
+
""" MySQL connection """
|
|
21
|
+
|
|
22
|
+
return pymysql.connect(host=host,
|
|
23
|
+
user=user,
|
|
24
|
+
port=port,
|
|
25
|
+
password=password,
|
|
26
|
+
database=database,
|
|
27
|
+
charset='utf8mb4',
|
|
28
|
+
client_flag=pymysql.constants.CLIENT.MULTI_STATEMENTS
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_pg_connection(host, user, port, password, database):
|
|
33
|
+
""" PostgreSQL connection """
|
|
34
|
+
|
|
35
|
+
return psycopg2.connect(host=host,
|
|
36
|
+
user=user,
|
|
37
|
+
port=port,
|
|
38
|
+
password=password,
|
|
39
|
+
dbname=database
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def get_connection(engine, host, user, port, password, database):
|
|
44
|
+
""" Get SQL connection """
|
|
45
|
+
|
|
46
|
+
if engine == 'mysql':
|
|
47
|
+
return get_mysql_connection(host, user, port, password, database)
|
|
48
|
+
elif engine == 'postgresql':
|
|
49
|
+
return get_pg_connection(host, user, port, password, database)
|
|
50
|
+
else:
|
|
51
|
+
raise RuntimeError(
|
|
52
|
+
'"%s" engine is not supported.' % (engine))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_cursor(connection):
|
|
56
|
+
""" Return connection cursor """
|
|
57
|
+
|
|
58
|
+
return connection.cursor()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def execute_query(cursor, query):
|
|
62
|
+
""" Run a query and yield each row """
|
|
63
|
+
|
|
64
|
+
cursor.execute(query)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def fetch_rows(cursor):
|
|
68
|
+
""" Fetch and yield rows """
|
|
69
|
+
|
|
70
|
+
for row in cursor.fetchall():
|
|
71
|
+
yield row
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def fetch_headers(cursor):
|
|
75
|
+
""" Return list of headers """
|
|
76
|
+
|
|
77
|
+
return [i[0] for i in cursor.description]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def discard_line(line):
|
|
81
|
+
""" Decide whether we should keep or discard a line """
|
|
82
|
+
|
|
83
|
+
if line[:1] in ['', '+', '(', '-']:
|
|
84
|
+
return True
|
|
85
|
+
|
|
86
|
+
return False
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def remove_leading_trailing_pipe(line):
|
|
90
|
+
""" Remove optional leading and trailing pipe """
|
|
91
|
+
|
|
92
|
+
return line.strip('|')
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def get_column_separator(input_):
|
|
96
|
+
""" Return the column separator """
|
|
97
|
+
""" This logic needs to be improved """
|
|
98
|
+
|
|
99
|
+
if input_.count('|') > input_.count('\t'):
|
|
100
|
+
return '|'
|
|
101
|
+
|
|
102
|
+
return '\t'
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def split_columns(line, separator='\t'):
|
|
106
|
+
""" Split a line with a "separator" """
|
|
107
|
+
|
|
108
|
+
return line.split(separator)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def strip_whitespaces(tpl):
|
|
112
|
+
""" Strip white spaces before and after each item """
|
|
113
|
+
|
|
114
|
+
return [item.strip() for item in tpl]
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def stringify_items(row):
|
|
118
|
+
""" Loop thru each item and Json-encode dicts """
|
|
119
|
+
|
|
120
|
+
row = list(row)
|
|
121
|
+
for k, item in enumerate(row):
|
|
122
|
+
if (isinstance(item, dict)):
|
|
123
|
+
row[k] = json.dumps(item)
|
|
124
|
+
|
|
125
|
+
return tuple(row)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def has_stdin_input():
|
|
129
|
+
""" Return `True` if there is an stdin input """
|
|
130
|
+
|
|
131
|
+
if not sys.stdin.isatty():
|
|
132
|
+
return True
|
|
133
|
+
|
|
134
|
+
return False
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def resolve_home_dir(destination):
|
|
138
|
+
""" Resolve `~` to a full path """
|
|
139
|
+
|
|
140
|
+
if destination[:1] == '~':
|
|
141
|
+
return expanduser("~") + destination[1:]
|
|
142
|
+
|
|
143
|
+
return destination
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def open_file(destination):
|
|
147
|
+
""" Open file """
|
|
148
|
+
|
|
149
|
+
global file_
|
|
150
|
+
|
|
151
|
+
file_ = open(destination, 'w+', newline='')
|
|
152
|
+
|
|
153
|
+
return file_
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def open_tempfile():
|
|
157
|
+
""" Open a temporary file """
|
|
158
|
+
|
|
159
|
+
global file_
|
|
160
|
+
|
|
161
|
+
file_ = tempfile.NamedTemporaryFile('w+', newline='', delete=False)
|
|
162
|
+
|
|
163
|
+
return file_
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def get_writer(file_, delimiter=',', quotechar='"'):
|
|
167
|
+
""" Return a writer object """
|
|
168
|
+
|
|
169
|
+
return csv.writer(
|
|
170
|
+
file_,
|
|
171
|
+
delimiter=delimiter,
|
|
172
|
+
quotechar=quotechar,
|
|
173
|
+
quoting=csv.QUOTE_MINIMAL
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def file_to_stdout(remove=False):
|
|
178
|
+
""" Print file content to stdout """
|
|
179
|
+
|
|
180
|
+
with open(file_.name) as f:
|
|
181
|
+
print(f.read())
|
|
182
|
+
|
|
183
|
+
# Remove the temporary file once it has been printed
|
|
184
|
+
if remove:
|
|
185
|
+
os.remove(file_.name)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def stdin_to_csv(delimiter=',', quotechar='"'):
|
|
189
|
+
""" Parse stdin and return output in a CSV format """
|
|
190
|
+
|
|
191
|
+
# Open CSV
|
|
192
|
+
with open_tempfile() as file_:
|
|
193
|
+
writer = get_writer(file_, delimiter=delimiter, quotechar=quotechar)
|
|
194
|
+
|
|
195
|
+
# Parse lines and add to file
|
|
196
|
+
separator = None
|
|
197
|
+
for line in sys.stdin:
|
|
198
|
+
|
|
199
|
+
if not discard_line(line):
|
|
200
|
+
# Get column separator
|
|
201
|
+
separator = get_column_separator(
|
|
202
|
+
line) if not separator else separator
|
|
203
|
+
|
|
204
|
+
# Remove leading and trailing |
|
|
205
|
+
line = remove_leading_trailing_pipe(line)
|
|
206
|
+
|
|
207
|
+
if line.strip():
|
|
208
|
+
# Split columns with separator
|
|
209
|
+
row = split_columns(line, separator)
|
|
210
|
+
|
|
211
|
+
# Add to CSV
|
|
212
|
+
row = strip_whitespaces(row)
|
|
213
|
+
|
|
214
|
+
# Write row
|
|
215
|
+
writer.writerow(row)
|
|
216
|
+
|
|
217
|
+
file_to_stdout(remove=True)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def query_to_csv(engine, host, user, port, password, database, query, headers=False, out_type='stdout', destination_file=None, delimiter=',', quotechar='"', print_info=1000):
|
|
221
|
+
""" Run a query and store the result to a CSV file """
|
|
222
|
+
|
|
223
|
+
# Get SQL connection
|
|
224
|
+
connection = get_connection(
|
|
225
|
+
engine=engine,
|
|
226
|
+
host=host,
|
|
227
|
+
user=user,
|
|
228
|
+
port=port,
|
|
229
|
+
password=password,
|
|
230
|
+
database=database
|
|
231
|
+
)
|
|
232
|
+
cursor = get_cursor(connection)
|
|
233
|
+
|
|
234
|
+
if out_type == 'file':
|
|
235
|
+
print('\n* Exporting rows...')
|
|
236
|
+
|
|
237
|
+
with open_tempfile() if out_type == 'stdout' else open_file(resolve_home_dir(destination_file)) as file_:
|
|
238
|
+
writer = get_writer(file_, delimiter=delimiter, quotechar=quotechar)
|
|
239
|
+
|
|
240
|
+
# Execute query
|
|
241
|
+
execute_query(cursor=cursor, query=query)
|
|
242
|
+
|
|
243
|
+
# Write headers if requested
|
|
244
|
+
if headers:
|
|
245
|
+
writer.writerow(fetch_headers(cursor=cursor))
|
|
246
|
+
|
|
247
|
+
# Write rows to CSV
|
|
248
|
+
i = 0
|
|
249
|
+
for row in fetch_rows(cursor=cursor):
|
|
250
|
+
# Increment row counter
|
|
251
|
+
i += 1
|
|
252
|
+
|
|
253
|
+
if out_type == 'file' and i % print_info == 0:
|
|
254
|
+
print(' ...%s rows written' % "{:,}".format(i))
|
|
255
|
+
|
|
256
|
+
row = stringify_items(row)
|
|
257
|
+
|
|
258
|
+
writer.writerow(row)
|
|
259
|
+
|
|
260
|
+
if out_type == 'file':
|
|
261
|
+
print(' ...done')
|
|
262
|
+
print('* The result has been exported to %s.\n' %
|
|
263
|
+
(destination_file))
|
|
264
|
+
|
|
265
|
+
# Print stdout
|
|
266
|
+
if out_type == 'stdout':
|
|
267
|
+
file_to_stdout(remove=True)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def main():
|
|
271
|
+
""" Parses arguments and run module """
|
|
272
|
+
|
|
273
|
+
# Intercept and parse stdin input
|
|
274
|
+
if has_stdin_input():
|
|
275
|
+
# Parse arguments
|
|
276
|
+
parser = argparse.ArgumentParser()
|
|
277
|
+
parser.add_argument("-D", "--delimiter",
|
|
278
|
+
help="CSV delimiter", default=',')
|
|
279
|
+
parser.add_argument("-Q", "--quotechar",
|
|
280
|
+
help="CSV quote character", default='"')
|
|
281
|
+
args = parser.parse_args()
|
|
282
|
+
|
|
283
|
+
return stdin_to_csv(delimiter=args.delimiter, quotechar=args.quotechar)
|
|
284
|
+
|
|
285
|
+
# Parse arguments
|
|
286
|
+
parser = argparse.ArgumentParser()
|
|
287
|
+
parser.add_argument("-e", "--engine", type=str, help="Database engine",
|
|
288
|
+
choices=['mysql', 'postgresql'], default='mysql')
|
|
289
|
+
parser.add_argument("-H", "--host", default="127.0.0.1",
|
|
290
|
+
help="Database host")
|
|
291
|
+
parser.add_argument("-P", "--port", type=int,
|
|
292
|
+
help="Database port")
|
|
293
|
+
parser.add_argument("-u", "--user", required=True, help="Database user")
|
|
294
|
+
parser.add_argument("-p", "--password", default='',
|
|
295
|
+
help="Database password")
|
|
296
|
+
parser.add_argument("-d", "--database", required=True,
|
|
297
|
+
help="Database name")
|
|
298
|
+
parser.add_argument("-q", "--query", required=True,
|
|
299
|
+
help="SQL query")
|
|
300
|
+
parser.add_argument("-o", "--out",
|
|
301
|
+
help="CSV destination", choices=['stdout', 'file'],
|
|
302
|
+
default='stdout')
|
|
303
|
+
parser.add_argument("-f", "--destination_file",
|
|
304
|
+
help="CSV destination file")
|
|
305
|
+
parser.add_argument("-D", "--delimiter", help="CSV delimiter", default=',')
|
|
306
|
+
parser.add_argument("-Q", "--quotechar",
|
|
307
|
+
help="CSV quote character", default='"')
|
|
308
|
+
parser.add_argument("-t", "--headers", action='store_true',
|
|
309
|
+
help="Include headers")
|
|
310
|
+
args = parser.parse_args()
|
|
311
|
+
|
|
312
|
+
# Set default port
|
|
313
|
+
if not args.port:
|
|
314
|
+
if args.engine == 'postgresql':
|
|
315
|
+
args.port = 5432 # PG default
|
|
316
|
+
else:
|
|
317
|
+
args.port = 3306 # MySQL default
|
|
318
|
+
|
|
319
|
+
# Force output to file if there is a file
|
|
320
|
+
if args.destination_file:
|
|
321
|
+
args.out = 'file'
|
|
322
|
+
|
|
323
|
+
query_to_csv(
|
|
324
|
+
engine=args.engine,
|
|
325
|
+
host=args.host,
|
|
326
|
+
user=args.user,
|
|
327
|
+
port=args.port,
|
|
328
|
+
password=args.password,
|
|
329
|
+
database=args.database,
|
|
330
|
+
query=args.query,
|
|
331
|
+
headers=args.headers,
|
|
332
|
+
out_type=args.out,
|
|
333
|
+
destination_file=args.destination_file,
|
|
334
|
+
delimiter=args.delimiter,
|
|
335
|
+
quotechar=args.quotechar
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
if __name__ == '__main__':
|
|
340
|
+
main()
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sql2csv
|
|
3
|
+
Version: 1.4
|
|
4
|
+
Summary: Run MySQL and PostgreSQL queries and store result in CSV
|
|
5
|
+
Author-email: Gabriel Bordeaux <pypi@gab.lc>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/gabfl/sql2csv
|
|
8
|
+
Classifier: Topic :: Database
|
|
9
|
+
Classifier: Topic :: Database :: Database Engines/Servers
|
|
10
|
+
Classifier: Operating System :: MacOS
|
|
11
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
12
|
+
Classifier: Natural Language :: English
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Development Status :: 4 - Beta
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: PyMySQL>=1.1
|
|
26
|
+
Requires-Dist: psycopg2-binary>=2.9.10
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# sql2csv
|
|
30
|
+
|
|
31
|
+
[](https://pypi.org/project/sql2csv)
|
|
32
|
+
[](https://github.com/gabfl/sql2csv/actions)
|
|
33
|
+
[](https://codecov.io/gh/gabfl/sql2csv)
|
|
34
|
+
[](https://raw.githubusercontent.com/gabfl/sql2csv/main/LICENSE)
|
|
35
|
+
|
|
36
|
+
Run MySQL and PostgreSQL queries and store the results in CSV.
|
|
37
|
+
|
|
38
|
+
## Why sql2csv
|
|
39
|
+
|
|
40
|
+
`sql2csv` is a small utility to run MySQL and PostgreSQL queries and store the output in a CSV file.
|
|
41
|
+
|
|
42
|
+
In some environments like when using MySQL or Aurora in AWS RDS, exporting queries' results to CSV is not available with native tools. `sql2csv` is a simple module that offers this feature.
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip3 install sql2csv
|
|
48
|
+
|
|
49
|
+
# Basic usage
|
|
50
|
+
mysql [...] -e "SELECT * FROM table" | sql2csv
|
|
51
|
+
# or
|
|
52
|
+
psql [...] -c "SELECT * FROM table" | sql2csv
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Example
|
|
56
|
+
|
|
57
|
+
### From stdin
|
|
58
|
+
|
|
59
|
+
For simple queries you can pipe a result directly from `mysql` or `psql` to `sql2csv`.
|
|
60
|
+
|
|
61
|
+
For more complex queries, it is recommended to use the CLI (see below) to ensure a properly formatted CSV.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
mysql -U root -p"secret" my_db -e "SELECT * FROM some_mysql_table;" | sql2csv
|
|
65
|
+
|
|
66
|
+
id,some_int,some_str,some_date
|
|
67
|
+
1,12,hello world,2018-12-01 12:23:12
|
|
68
|
+
2,15,hello,2018-12-05 12:18:12
|
|
69
|
+
3,18,world,2018-12-08 12:17:12
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
psql -U postgres my_db -c "SELECT * FROM some_pg_table" | sql2csv
|
|
74
|
+
|
|
75
|
+
id,some_int,some_str,some_date
|
|
76
|
+
1,12,hello world,2018-12-01 12:23:12
|
|
77
|
+
2,15,hello,2018-12-05 12:18:12
|
|
78
|
+
3,18,world,2018-12-08 12:17:12
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Using `sql2csv` CLI
|
|
82
|
+
|
|
83
|
+
#### Output to stdout
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
$ sql2csv --engine mysql \
|
|
87
|
+
--database my_db --user root --password "secret" \
|
|
88
|
+
--query "SELECT * FROM some_mysql_table"
|
|
89
|
+
|
|
90
|
+
1,12,hello world,2018-12-01 12:23:12
|
|
91
|
+
2,15,hello,2018-12-05 12:18:12
|
|
92
|
+
3,18,world,2018-12-08 12:17:12
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Output saved in a file
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
$ sql2csv --engine mysql \
|
|
99
|
+
--database my_db --user root --password "secret" \
|
|
100
|
+
--query "SELECT * FROM some_mysql_table" \
|
|
101
|
+
--headers \
|
|
102
|
+
--out file --destination_file export.csv
|
|
103
|
+
|
|
104
|
+
# * Exporting rows...
|
|
105
|
+
# ...done
|
|
106
|
+
# * The result has been exported to export.csv.
|
|
107
|
+
|
|
108
|
+
$ cat export.csv
|
|
109
|
+
id,some_int,some_str,some_date
|
|
110
|
+
1,12,hello world,2018-12-01 12:23:12
|
|
111
|
+
2,15,hello,2018-12-05 12:18:12
|
|
112
|
+
3,18,world,2018-12-08 12:17:12
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Usage
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
usage: sql2csv [-h] [-e {mysql,postgresql}] [-H HOST] [-P PORT] -u USER
|
|
119
|
+
[-p PASSWORD] -d DATABASE -q QUERY [-o {stdout,file}]
|
|
120
|
+
[-f DESTINATION_FILE] [-D DELIMITER] [-Q QUOTECHAR] [-t]
|
|
121
|
+
|
|
122
|
+
optional arguments:
|
|
123
|
+
-h, --help show this help message and exit
|
|
124
|
+
-e {mysql,postgresql}, --engine {mysql,postgresql}
|
|
125
|
+
Database engine
|
|
126
|
+
-H HOST, --host HOST Database host
|
|
127
|
+
-P PORT, --port PORT Database port
|
|
128
|
+
-u USER, --user USER Database user
|
|
129
|
+
-p PASSWORD, --password PASSWORD
|
|
130
|
+
Database password
|
|
131
|
+
-d DATABASE, --database DATABASE
|
|
132
|
+
Database name
|
|
133
|
+
-q QUERY, --query QUERY
|
|
134
|
+
SQL query
|
|
135
|
+
-o {stdout,file}, --out {stdout,file}
|
|
136
|
+
CSV destination
|
|
137
|
+
-f DESTINATION_FILE, --destination_file DESTINATION_FILE
|
|
138
|
+
CSV destination file
|
|
139
|
+
-D DELIMITER, --delimiter DELIMITER
|
|
140
|
+
CSV delimiter
|
|
141
|
+
-Q QUOTECHAR, --quotechar QUOTECHAR
|
|
142
|
+
CSV quote character
|
|
143
|
+
-t, --headers Include headers
|
|
144
|
+
```
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
sql2csv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
sql2csv/__main__.py,sha256=elJffGxPxqOYcg0q8wZAUcysRB31g3mMOxuEOJYOyWw,69
|
|
3
|
+
sql2csv/sql2csv.py,sha256=CDZpJJsIsih91juzf5OMQSitIl7jrmJdTNRZkqwvfSw,9054
|
|
4
|
+
sql2csv-1.4.dist-info/licenses/LICENSE,sha256=WqS7GgVJk_T1GouVCLKKsR1q83EOah9Hpb72mq0pQ64,1073
|
|
5
|
+
sql2csv-1.4.dist-info/METADATA,sha256=n2caXnT9zGhqP2wCabzqKEkE2cgfPccsvqar2uvfmik,4605
|
|
6
|
+
sql2csv-1.4.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
7
|
+
sql2csv-1.4.dist-info/entry_points.txt,sha256=r6P7X-kTfb-_i1IIPX2R6e8v9ypJeVQSHO9nMXT5teU,49
|
|
8
|
+
sql2csv-1.4.dist-info/top_level.txt,sha256=cNCzLiAnuxrr1OQUoDDLb_6mkjGLOwEcqi0ErtFrfl0,8
|
|
9
|
+
sql2csv-1.4.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Gabriel Bordeaux
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
sql2csv
|