sqlutilpy 0.24.0__tar.gz → 0.26.0__tar.gz
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.
- {sqlutilpy-0.24.0/src/sqlutilpy.egg-info → sqlutilpy-0.26.0}/PKG-INFO +28 -21
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/README.md +25 -19
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/src/sqlutilpy/sqlutil.py +13 -9
- sqlutilpy-0.26.0/src/sqlutilpy/version.py +1 -0
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0/src/sqlutilpy.egg-info}/PKG-INFO +28 -21
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/src/sqlutilpy.egg-info/SOURCES.txt +1 -0
- sqlutilpy-0.26.0/tests/test_duckdb.py +32 -0
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/tests/test_pg.py +3 -3
- sqlutilpy-0.24.0/src/sqlutilpy/version.py +0 -1
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/LICENSE.txt +0 -0
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/MANIFEST.in +0 -0
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/pyproject.toml +0 -0
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/setup.cfg +0 -0
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/src/sqlutilpy/__init__.py +0 -0
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/src/sqlutilpy.egg-info/dependency_links.txt +0 -0
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/src/sqlutilpy.egg-info/requires.txt +0 -0
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/src/sqlutilpy.egg-info/top_level.txt +0 -0
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/tests/killer.py +0 -0
- {sqlutilpy-0.24.0 → sqlutilpy-0.26.0}/tests/test_sqlite.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlutilpy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.26.0
|
|
4
4
|
Summary: Database query code returning numpy arrays
|
|
5
5
|
Author-email: "Sergey E. Koposov" <skoposov@ed.ac.uk>
|
|
6
6
|
License: BSD
|
|
@@ -16,6 +16,7 @@ Requires-Dist: numpy
|
|
|
16
16
|
Requires-Dist: psycopg[binary]
|
|
17
17
|
Requires-Dist: numpydoc
|
|
18
18
|
Requires-Dist: numpy
|
|
19
|
+
Dynamic: license-file
|
|
19
20
|
|
|
20
21
|
[](https://github.com/segasai/sqlutilpy/actions)
|
|
21
22
|
[](http://sqlutilpy.readthedocs.io/en/latest/?badge=latest)
|
|
@@ -25,8 +26,8 @@ Requires-Dist: numpy
|
|
|
25
26
|
# sqlutilpy
|
|
26
27
|
Python module to query SQL databases and return numpy arrays, upload
|
|
27
28
|
tables and run join queries involving local arrays and the tables in the DB.
|
|
28
|
-
This module is optimized to
|
|
29
|
-
The module
|
|
29
|
+
This module is optimized to deal efficiently with query results with millions of rows.
|
|
30
|
+
The module works with PostgreSQL, SQLite and DuckDB databases.
|
|
30
31
|
|
|
31
32
|
The full documentation is available [here](http://sqlutilpy.readthedocs.io/en/latest/)
|
|
32
33
|
|
|
@@ -40,13 +41,14 @@ pip install sqlutilpy
|
|
|
40
41
|
```
|
|
41
42
|
## Authentication
|
|
42
43
|
|
|
43
|
-
Throughout this readme, I will assume that
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
Throughout this readme, I will assume that if you are using PostgreSQL, then
|
|
45
|
+
the .pgpass file ( https://www.postgresql.org/docs/11/libpq-pgpass.html )
|
|
46
|
+
has been created with your login/password details for Postgresql. If that is not the case, many of the
|
|
47
|
+
commands given below will also need user='....' and password='...' options.
|
|
46
48
|
|
|
47
49
|
## Connection information
|
|
48
50
|
|
|
49
|
-
Most of the sqlutilpy commands require hostname, database name
|
|
51
|
+
Most of the `sqlutilpy` commands require hostname, database name.
|
|
50
52
|
If you don't want to always type it, you can use standard PostgreSQL environment variables
|
|
51
53
|
like PGPORT, PGDATABASE, PGUSER, PGHOST for the port, database name, user name and hostname
|
|
52
54
|
of the connection.
|
|
@@ -54,7 +56,8 @@ of the connection.
|
|
|
54
56
|
|
|
55
57
|
## Querying the database and retrieving the results
|
|
56
58
|
|
|
57
|
-
This command will run the query and put the columns into variables ra,dec
|
|
59
|
+
This command will run the query and put the columns into variables ra,dec:
|
|
60
|
+
|
|
58
61
|
```python
|
|
59
62
|
import sqlutilpy
|
|
60
63
|
ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
@@ -62,23 +65,28 @@ ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
|
62
65
|
db='THE_NAME_OF_MY_DB')
|
|
63
66
|
```
|
|
64
67
|
|
|
65
|
-
By default sqlutilpy.get executes the query and returns the tuple with
|
|
66
|
-
|
|
68
|
+
By default `sqlutilpy.get` executes the query and returns the tuple with
|
|
69
|
+
arrays. One array for each column in the query result.
|
|
70
|
+
You can return the results as dictionary using `asDict` option.
|
|
67
71
|
|
|
68
72
|
## Uploading your arrays as column in a table
|
|
69
73
|
|
|
74
|
+
You can use `sqlutilpy.upload` to upload your arrays as columns in a table.
|
|
75
|
+
|
|
70
76
|
```python
|
|
71
77
|
x = np.arange(10)
|
|
72
78
|
y = x**.5
|
|
73
79
|
sqlutilpy.upload('mytable',(x,y),('xcol','ycol'))
|
|
74
80
|
```
|
|
75
|
-
This will create a table called mytable with columns xcol and ycol
|
|
81
|
+
This will create a table called `mytable` with columns `xcol` and `ycol`
|
|
76
82
|
|
|
77
83
|
## Join query involving your local data and the database table
|
|
78
84
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
you
|
|
85
|
+
Sometimes it is beneficial to run a join query involving your local data and the data in the database.
|
|
86
|
+
|
|
87
|
+
Imagine you have arrays `myid` and `y` and you want to extract all the
|
|
88
|
+
information from `somebigtable` for objects with `id=myid`. In principle,
|
|
89
|
+
you could upload the arrays in the DB and run a query, but `local_join` function does that for you.
|
|
82
90
|
|
|
83
91
|
```python
|
|
84
92
|
myid = np.arange(10)
|
|
@@ -89,15 +97,14 @@ R=sqlutilpy.local_join('''select * from mytmptable as m,
|
|
|
89
97
|
'mytmptable',(myid, y),('myid','ycol'))
|
|
90
98
|
```
|
|
91
99
|
|
|
92
|
-
It executes a query as if
|
|
93
|
-
it uploads the data to the
|
|
100
|
+
It executes a query as if your arrays were in `mytmptable`. What happens behind the scenes
|
|
101
|
+
is that it uploads the data to the database and runs a query against it.
|
|
94
102
|
|
|
95
103
|
## Keeping the connection open.
|
|
96
104
|
|
|
97
105
|
Often it is beneficial to preserve an open connection to the database. You can do that if you first
|
|
98
|
-
obtain the connection using sqlutilpy.getConnection() and then provide it directly
|
|
99
|
-
to sqlutil.get() and
|
|
100
|
-
```python
|
|
106
|
+
obtain the connection using `sqlutilpy.getConnection()` and then provide it directly
|
|
107
|
+
to `sqlutil.get()` and similar commands using `conn=` keyword:
|
|
101
108
|
conn = sqlutilpy.getConnection(db='mydb', user='meuser', password='something', host='hostname')
|
|
102
109
|
R= sqlutilpy.get('select 1', conn=conn)
|
|
103
110
|
R1= sqlutilpy.get('select 1', conn=conn)
|
|
@@ -105,5 +112,5 @@ R1= sqlutilpy.get('select 1', conn=conn)
|
|
|
105
112
|
|
|
106
113
|
# How to cite the software
|
|
107
114
|
|
|
108
|
-
If you use this package, please cite it through
|
|
115
|
+
If you use this package, please cite it through Zenodo https://doi.org/10.5281/zenodo.5160118
|
|
109
116
|
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
# sqlutilpy
|
|
7
7
|
Python module to query SQL databases and return numpy arrays, upload
|
|
8
8
|
tables and run join queries involving local arrays and the tables in the DB.
|
|
9
|
-
This module is optimized to
|
|
10
|
-
The module
|
|
9
|
+
This module is optimized to deal efficiently with query results with millions of rows.
|
|
10
|
+
The module works with PostgreSQL, SQLite and DuckDB databases.
|
|
11
11
|
|
|
12
12
|
The full documentation is available [here](http://sqlutilpy.readthedocs.io/en/latest/)
|
|
13
13
|
|
|
@@ -21,13 +21,14 @@ pip install sqlutilpy
|
|
|
21
21
|
```
|
|
22
22
|
## Authentication
|
|
23
23
|
|
|
24
|
-
Throughout this readme, I will assume that
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
Throughout this readme, I will assume that if you are using PostgreSQL, then
|
|
25
|
+
the .pgpass file ( https://www.postgresql.org/docs/11/libpq-pgpass.html )
|
|
26
|
+
has been created with your login/password details for Postgresql. If that is not the case, many of the
|
|
27
|
+
commands given below will also need user='....' and password='...' options.
|
|
27
28
|
|
|
28
29
|
## Connection information
|
|
29
30
|
|
|
30
|
-
Most of the sqlutilpy commands require hostname, database name
|
|
31
|
+
Most of the `sqlutilpy` commands require hostname, database name.
|
|
31
32
|
If you don't want to always type it, you can use standard PostgreSQL environment variables
|
|
32
33
|
like PGPORT, PGDATABASE, PGUSER, PGHOST for the port, database name, user name and hostname
|
|
33
34
|
of the connection.
|
|
@@ -35,7 +36,8 @@ of the connection.
|
|
|
35
36
|
|
|
36
37
|
## Querying the database and retrieving the results
|
|
37
38
|
|
|
38
|
-
This command will run the query and put the columns into variables ra,dec
|
|
39
|
+
This command will run the query and put the columns into variables ra,dec:
|
|
40
|
+
|
|
39
41
|
```python
|
|
40
42
|
import sqlutilpy
|
|
41
43
|
ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
@@ -43,23 +45,28 @@ ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
|
43
45
|
db='THE_NAME_OF_MY_DB')
|
|
44
46
|
```
|
|
45
47
|
|
|
46
|
-
By default sqlutilpy.get executes the query and returns the tuple with
|
|
47
|
-
|
|
48
|
+
By default `sqlutilpy.get` executes the query and returns the tuple with
|
|
49
|
+
arrays. One array for each column in the query result.
|
|
50
|
+
You can return the results as dictionary using `asDict` option.
|
|
48
51
|
|
|
49
52
|
## Uploading your arrays as column in a table
|
|
50
53
|
|
|
54
|
+
You can use `sqlutilpy.upload` to upload your arrays as columns in a table.
|
|
55
|
+
|
|
51
56
|
```python
|
|
52
57
|
x = np.arange(10)
|
|
53
58
|
y = x**.5
|
|
54
59
|
sqlutilpy.upload('mytable',(x,y),('xcol','ycol'))
|
|
55
60
|
```
|
|
56
|
-
This will create a table called mytable with columns xcol and ycol
|
|
61
|
+
This will create a table called `mytable` with columns `xcol` and `ycol`
|
|
57
62
|
|
|
58
63
|
## Join query involving your local data and the database table
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
you
|
|
65
|
+
Sometimes it is beneficial to run a join query involving your local data and the data in the database.
|
|
66
|
+
|
|
67
|
+
Imagine you have arrays `myid` and `y` and you want to extract all the
|
|
68
|
+
information from `somebigtable` for objects with `id=myid`. In principle,
|
|
69
|
+
you could upload the arrays in the DB and run a query, but `local_join` function does that for you.
|
|
63
70
|
|
|
64
71
|
```python
|
|
65
72
|
myid = np.arange(10)
|
|
@@ -70,15 +77,14 @@ R=sqlutilpy.local_join('''select * from mytmptable as m,
|
|
|
70
77
|
'mytmptable',(myid, y),('myid','ycol'))
|
|
71
78
|
```
|
|
72
79
|
|
|
73
|
-
It executes a query as if
|
|
74
|
-
it uploads the data to the
|
|
80
|
+
It executes a query as if your arrays were in `mytmptable`. What happens behind the scenes
|
|
81
|
+
is that it uploads the data to the database and runs a query against it.
|
|
75
82
|
|
|
76
83
|
## Keeping the connection open.
|
|
77
84
|
|
|
78
85
|
Often it is beneficial to preserve an open connection to the database. You can do that if you first
|
|
79
|
-
obtain the connection using sqlutilpy.getConnection() and then provide it directly
|
|
80
|
-
to sqlutil.get() and
|
|
81
|
-
```python
|
|
86
|
+
obtain the connection using `sqlutilpy.getConnection()` and then provide it directly
|
|
87
|
+
to `sqlutil.get()` and similar commands using `conn=` keyword:
|
|
82
88
|
conn = sqlutilpy.getConnection(db='mydb', user='meuser', password='something', host='hostname')
|
|
83
89
|
R= sqlutilpy.get('select 1', conn=conn)
|
|
84
90
|
R1= sqlutilpy.get('select 1', conn=conn)
|
|
@@ -86,5 +92,5 @@ R1= sqlutilpy.get('select 1', conn=conn)
|
|
|
86
92
|
|
|
87
93
|
# How to cite the software
|
|
88
94
|
|
|
89
|
-
If you use this package, please cite it through
|
|
95
|
+
If you use this package, please cite it through Zenodo https://doi.org/10.5281/zenodo.5160118
|
|
90
96
|
|
|
@@ -7,7 +7,6 @@ import psycopg
|
|
|
7
7
|
import threading
|
|
8
8
|
import collections
|
|
9
9
|
import warnings
|
|
10
|
-
from numpy.core import numeric as sb
|
|
11
10
|
|
|
12
11
|
try:
|
|
13
12
|
import astropy.table as atpy
|
|
@@ -92,6 +91,9 @@ def getConnection(db=None,
|
|
|
92
91
|
if timeout is None:
|
|
93
92
|
timeout = 5
|
|
94
93
|
conn = sqlite3.connect(db, timeout=timeout)
|
|
94
|
+
elif driver == 'duckdb':
|
|
95
|
+
import duckdb
|
|
96
|
+
conn = duckdb.connect(db)
|
|
95
97
|
else:
|
|
96
98
|
raise Exception("Unknown driver")
|
|
97
99
|
return conn
|
|
@@ -137,12 +139,12 @@ def __fromrecords(recList, dtype=None, intNullVal=None):
|
|
|
137
139
|
"""
|
|
138
140
|
|
|
139
141
|
shape = None
|
|
140
|
-
descr =
|
|
142
|
+
descr = np.dtype((np.record, dtype))
|
|
141
143
|
try:
|
|
142
|
-
retval =
|
|
144
|
+
retval = np.array(recList, dtype=descr)
|
|
143
145
|
except TypeError: # list of lists instead of list of tuples
|
|
144
146
|
shape = (len(recList), )
|
|
145
|
-
_array = np.
|
|
147
|
+
_array = np.recarray(shape, descr)
|
|
146
148
|
try:
|
|
147
149
|
for k in range(_array.size):
|
|
148
150
|
_array[k] = tuple(recList[k])
|
|
@@ -170,7 +172,7 @@ def __fromrecords(recList, dtype=None, intNullVal=None):
|
|
|
170
172
|
if shape is not None and retval.shape != shape:
|
|
171
173
|
retval.shape = shape
|
|
172
174
|
|
|
173
|
-
res = retval.view(numpy.
|
|
175
|
+
res = retval.view(numpy.recarray)
|
|
174
176
|
|
|
175
177
|
return res
|
|
176
178
|
|
|
@@ -210,6 +212,7 @@ def __getDType(row, typeCodes, strLength):
|
|
|
210
212
|
1022: 'f8',
|
|
211
213
|
1700: 'f8', # numeric
|
|
212
214
|
1114: '<M8[us]', # timestamp
|
|
215
|
+
1184: '<M8[us]', # timestamp with timezone
|
|
213
216
|
1082: '<M8[us]', # date
|
|
214
217
|
25: '|U%d',
|
|
215
218
|
1042: '|U%d', # character()
|
|
@@ -407,7 +410,8 @@ def get(query,
|
|
|
407
410
|
proc.join(0.2)
|
|
408
411
|
# in the converter process
|
|
409
412
|
if proc.is_alive():
|
|
410
|
-
|
|
413
|
+
# could not kill
|
|
414
|
+
pass
|
|
411
415
|
raise
|
|
412
416
|
if proc is not None:
|
|
413
417
|
proc.join()
|
|
@@ -423,14 +427,14 @@ def get(query,
|
|
|
423
427
|
tups = cur.fetchall()
|
|
424
428
|
colNames = [_tmp[0] for _tmp in cur.description]
|
|
425
429
|
if len(tups) > 0:
|
|
426
|
-
res = numpy.
|
|
430
|
+
res = numpy.rec.array(tups)
|
|
427
431
|
else:
|
|
428
432
|
return [[]] * len(cur.description)
|
|
429
433
|
elif driver == 'duckdb':
|
|
430
434
|
tups = cur.fetchall()
|
|
431
435
|
colNames = [_tmp[0] for _tmp in cur.description]
|
|
432
436
|
if len(tups) > 0:
|
|
433
|
-
res = numpy.
|
|
437
|
+
res = numpy.rec.array(tups)
|
|
434
438
|
else:
|
|
435
439
|
return [[]] * len(cur.description)
|
|
436
440
|
|
|
@@ -735,7 +739,7 @@ table/pandas/dictionary or provide a separate list of arrays and their names')
|
|
|
735
739
|
cur.execute(query1)
|
|
736
740
|
nsplit = 100000
|
|
737
741
|
N = len(arrays[0])
|
|
738
|
-
names = ','.join(names)
|
|
742
|
+
names = ','.join(['"%s"' % _ for _ in names])
|
|
739
743
|
for i in range(0, N, nsplit):
|
|
740
744
|
try:
|
|
741
745
|
with cur.copy(f'''copy {tableName}({names}) from stdin
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.26.0'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlutilpy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.26.0
|
|
4
4
|
Summary: Database query code returning numpy arrays
|
|
5
5
|
Author-email: "Sergey E. Koposov" <skoposov@ed.ac.uk>
|
|
6
6
|
License: BSD
|
|
@@ -16,6 +16,7 @@ Requires-Dist: numpy
|
|
|
16
16
|
Requires-Dist: psycopg[binary]
|
|
17
17
|
Requires-Dist: numpydoc
|
|
18
18
|
Requires-Dist: numpy
|
|
19
|
+
Dynamic: license-file
|
|
19
20
|
|
|
20
21
|
[](https://github.com/segasai/sqlutilpy/actions)
|
|
21
22
|
[](http://sqlutilpy.readthedocs.io/en/latest/?badge=latest)
|
|
@@ -25,8 +26,8 @@ Requires-Dist: numpy
|
|
|
25
26
|
# sqlutilpy
|
|
26
27
|
Python module to query SQL databases and return numpy arrays, upload
|
|
27
28
|
tables and run join queries involving local arrays and the tables in the DB.
|
|
28
|
-
This module is optimized to
|
|
29
|
-
The module
|
|
29
|
+
This module is optimized to deal efficiently with query results with millions of rows.
|
|
30
|
+
The module works with PostgreSQL, SQLite and DuckDB databases.
|
|
30
31
|
|
|
31
32
|
The full documentation is available [here](http://sqlutilpy.readthedocs.io/en/latest/)
|
|
32
33
|
|
|
@@ -40,13 +41,14 @@ pip install sqlutilpy
|
|
|
40
41
|
```
|
|
41
42
|
## Authentication
|
|
42
43
|
|
|
43
|
-
Throughout this readme, I will assume that
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
Throughout this readme, I will assume that if you are using PostgreSQL, then
|
|
45
|
+
the .pgpass file ( https://www.postgresql.org/docs/11/libpq-pgpass.html )
|
|
46
|
+
has been created with your login/password details for Postgresql. If that is not the case, many of the
|
|
47
|
+
commands given below will also need user='....' and password='...' options.
|
|
46
48
|
|
|
47
49
|
## Connection information
|
|
48
50
|
|
|
49
|
-
Most of the sqlutilpy commands require hostname, database name
|
|
51
|
+
Most of the `sqlutilpy` commands require hostname, database name.
|
|
50
52
|
If you don't want to always type it, you can use standard PostgreSQL environment variables
|
|
51
53
|
like PGPORT, PGDATABASE, PGUSER, PGHOST for the port, database name, user name and hostname
|
|
52
54
|
of the connection.
|
|
@@ -54,7 +56,8 @@ of the connection.
|
|
|
54
56
|
|
|
55
57
|
## Querying the database and retrieving the results
|
|
56
58
|
|
|
57
|
-
This command will run the query and put the columns into variables ra,dec
|
|
59
|
+
This command will run the query and put the columns into variables ra,dec:
|
|
60
|
+
|
|
58
61
|
```python
|
|
59
62
|
import sqlutilpy
|
|
60
63
|
ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
@@ -62,23 +65,28 @@ ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
|
62
65
|
db='THE_NAME_OF_MY_DB')
|
|
63
66
|
```
|
|
64
67
|
|
|
65
|
-
By default sqlutilpy.get executes the query and returns the tuple with
|
|
66
|
-
|
|
68
|
+
By default `sqlutilpy.get` executes the query and returns the tuple with
|
|
69
|
+
arrays. One array for each column in the query result.
|
|
70
|
+
You can return the results as dictionary using `asDict` option.
|
|
67
71
|
|
|
68
72
|
## Uploading your arrays as column in a table
|
|
69
73
|
|
|
74
|
+
You can use `sqlutilpy.upload` to upload your arrays as columns in a table.
|
|
75
|
+
|
|
70
76
|
```python
|
|
71
77
|
x = np.arange(10)
|
|
72
78
|
y = x**.5
|
|
73
79
|
sqlutilpy.upload('mytable',(x,y),('xcol','ycol'))
|
|
74
80
|
```
|
|
75
|
-
This will create a table called mytable with columns xcol and ycol
|
|
81
|
+
This will create a table called `mytable` with columns `xcol` and `ycol`
|
|
76
82
|
|
|
77
83
|
## Join query involving your local data and the database table
|
|
78
84
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
you
|
|
85
|
+
Sometimes it is beneficial to run a join query involving your local data and the data in the database.
|
|
86
|
+
|
|
87
|
+
Imagine you have arrays `myid` and `y` and you want to extract all the
|
|
88
|
+
information from `somebigtable` for objects with `id=myid`. In principle,
|
|
89
|
+
you could upload the arrays in the DB and run a query, but `local_join` function does that for you.
|
|
82
90
|
|
|
83
91
|
```python
|
|
84
92
|
myid = np.arange(10)
|
|
@@ -89,15 +97,14 @@ R=sqlutilpy.local_join('''select * from mytmptable as m,
|
|
|
89
97
|
'mytmptable',(myid, y),('myid','ycol'))
|
|
90
98
|
```
|
|
91
99
|
|
|
92
|
-
It executes a query as if
|
|
93
|
-
it uploads the data to the
|
|
100
|
+
It executes a query as if your arrays were in `mytmptable`. What happens behind the scenes
|
|
101
|
+
is that it uploads the data to the database and runs a query against it.
|
|
94
102
|
|
|
95
103
|
## Keeping the connection open.
|
|
96
104
|
|
|
97
105
|
Often it is beneficial to preserve an open connection to the database. You can do that if you first
|
|
98
|
-
obtain the connection using sqlutilpy.getConnection() and then provide it directly
|
|
99
|
-
to sqlutil.get() and
|
|
100
|
-
```python
|
|
106
|
+
obtain the connection using `sqlutilpy.getConnection()` and then provide it directly
|
|
107
|
+
to `sqlutil.get()` and similar commands using `conn=` keyword:
|
|
101
108
|
conn = sqlutilpy.getConnection(db='mydb', user='meuser', password='something', host='hostname')
|
|
102
109
|
R= sqlutilpy.get('select 1', conn=conn)
|
|
103
110
|
R1= sqlutilpy.get('select 1', conn=conn)
|
|
@@ -105,5 +112,5 @@ R1= sqlutilpy.get('select 1', conn=conn)
|
|
|
105
112
|
|
|
106
113
|
# How to cite the software
|
|
107
114
|
|
|
108
|
-
If you use this package, please cite it through
|
|
115
|
+
If you use this package, please cite it through Zenodo https://doi.org/10.5281/zenodo.5160118
|
|
109
116
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import os
|
|
3
|
+
import sqlutilpy as sqlutil
|
|
4
|
+
import duckdb
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@pytest.fixture()
|
|
8
|
+
def setup():
|
|
9
|
+
fname = 'duck.db'
|
|
10
|
+
kw = dict(db=fname, driver='duckdb')
|
|
11
|
+
conn = duckdb.connect(fname)
|
|
12
|
+
cur = conn.cursor()
|
|
13
|
+
cur.execute('create table tmp (a int, b double precision)')
|
|
14
|
+
cur.execute('insert into tmp values(1,2), (2,3), (3,4), (4,5);')
|
|
15
|
+
conn.commit()
|
|
16
|
+
yield kw
|
|
17
|
+
os.unlink(fname)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_simple(setup):
|
|
21
|
+
a, b = sqlutil.get('select a,b from tmp', **setup)
|
|
22
|
+
assert (len(a) == 4)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_preamb(setup):
|
|
26
|
+
a, b = sqlutil.get('select a,b from tmp', preamb='select 1', **setup)
|
|
27
|
+
assert (len(a) == 4)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_empty(setup):
|
|
31
|
+
a, b = sqlutil.get('select a,b from tmp where a<0', **setup)
|
|
32
|
+
assert (len(a) == 0)
|
|
@@ -340,12 +340,12 @@ def test_upload(setup):
|
|
|
340
340
|
'xi32': xi32,
|
|
341
341
|
'xi64': xi64,
|
|
342
342
|
'xf32': xf32,
|
|
343
|
-
'
|
|
343
|
+
'XF64': xf64, # one uppercase
|
|
344
344
|
'xbool': xbool
|
|
345
345
|
})
|
|
346
346
|
sqlutil.upload(mytab, astroTab, **kw)
|
|
347
347
|
yi16, yi32, yi64, yf32, yf64, ybool = sqlutil.get(
|
|
348
|
-
'''select xi16,xi32,xi64,xf32,
|
|
348
|
+
'''select xi16,xi32,xi64,xf32,"XF64",xbool from %s''' % (mytab), **kw)
|
|
349
349
|
try:
|
|
350
350
|
assert ((xi16 == yi16).all())
|
|
351
351
|
assert ((xi32 == yi32).all())
|
|
@@ -357,7 +357,7 @@ def test_upload(setup):
|
|
|
357
357
|
sqlutil.execute('drop table %s' % mytab, **kw)
|
|
358
358
|
sqlutil.upload(mytab, astroTab.to_pandas(), **kw)
|
|
359
359
|
yi16, yi32, yi64, yf32, yf64, ybool = sqlutil.get(
|
|
360
|
-
'''select xi16,xi32,xi64,xf32,
|
|
360
|
+
'''select xi16,xi32,xi64,xf32,"XF64",xbool from %s''' % (mytab), **kw)
|
|
361
361
|
try:
|
|
362
362
|
assert ((xi16 == yi16).all())
|
|
363
363
|
assert ((xi32 == yi32).all())
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.24.0'
|
|
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
|