sqlutilpy 0.21.0__tar.gz → 0.23.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.21.0/py/sqlutilpy.egg-info → sqlutilpy-0.23.0}/PKG-INFO +34 -20
- {sqlutilpy-0.21.0 → sqlutilpy-0.23.0}/README.md +27 -14
- sqlutilpy-0.23.0/pyproject.toml +33 -0
- sqlutilpy-0.23.0/setup.cfg +4 -0
- {sqlutilpy-0.21.0/py → sqlutilpy-0.23.0/src}/sqlutilpy/sqlutil.py +34 -49
- sqlutilpy-0.23.0/src/sqlutilpy/version.py +1 -0
- {sqlutilpy-0.21.0 → sqlutilpy-0.23.0/src/sqlutilpy.egg-info}/PKG-INFO +34 -20
- sqlutilpy-0.23.0/src/sqlutilpy.egg-info/SOURCES.txt +15 -0
- sqlutilpy-0.23.0/src/sqlutilpy.egg-info/requires.txt +4 -0
- sqlutilpy-0.23.0/tests/test_pg.py +446 -0
- sqlutilpy-0.23.0/tests/test_sqlite.py +32 -0
- sqlutilpy-0.21.0/py/sqlutilpy/version.py +0 -1
- sqlutilpy-0.21.0/py/sqlutilpy.egg-info/SOURCES.txt +0 -16
- sqlutilpy-0.21.0/py/sqlutilpy.egg-info/requires.txt +0 -3
- sqlutilpy-0.21.0/requirements.txt +0 -3
- sqlutilpy-0.21.0/setup.cfg +0 -7
- sqlutilpy-0.21.0/setup.py +0 -65
- sqlutilpy-0.21.0/tests/sqlutil_test.py +0 -439
- {sqlutilpy-0.21.0 → sqlutilpy-0.23.0}/LICENSE.txt +0 -0
- {sqlutilpy-0.21.0 → sqlutilpy-0.23.0}/MANIFEST.in +0 -0
- {sqlutilpy-0.21.0/py → sqlutilpy-0.23.0/src}/sqlutilpy/__init__.py +0 -0
- {sqlutilpy-0.21.0/py → sqlutilpy-0.23.0/src}/sqlutilpy.egg-info/dependency_links.txt +0 -0
- {sqlutilpy-0.21.0/py → sqlutilpy-0.23.0/src}/sqlutilpy.egg-info/top_level.txt +0 -0
- {sqlutilpy-0.21.0 → sqlutilpy-0.23.0}/tests/killer.py +0 -0
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sqlutilpy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.23.0
|
|
4
4
|
Summary: Database query code returning numpy arrays
|
|
5
|
-
|
|
6
|
-
Author: Sergey Koposov
|
|
7
|
-
Author-email: skoposov@ed.ac.uk
|
|
5
|
+
Author-email: "Sergey E. Koposov" <skoposov@ed.ac.uk>
|
|
8
6
|
License: BSD
|
|
7
|
+
Project-URL: Homepage, https://github.com/segasai/sqlutilpy
|
|
9
8
|
Keywords: numpy postgresql query sql sqlite array
|
|
10
9
|
Classifier: Development Status :: 3 - Alpha
|
|
11
|
-
Classifier: Topic :: Utilities
|
|
12
10
|
Classifier: License :: OSI Approved :: BSD License
|
|
11
|
+
Classifier: Topic :: Utilities
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE.txt
|
|
15
15
|
Requires-Dist: numpy
|
|
16
|
-
Requires-Dist:
|
|
16
|
+
Requires-Dist: psycopg[binary]
|
|
17
17
|
Requires-Dist: numpydoc
|
|
18
|
+
Requires-Dist: numpy
|
|
18
19
|
|
|
19
20
|
[](https://github.com/segasai/sqlutilpy/actions)
|
|
20
21
|
[](http://sqlutilpy.readthedocs.io/en/latest/?badge=latest)
|
|
@@ -24,7 +25,8 @@ Requires-Dist: numpydoc
|
|
|
24
25
|
# sqlutilpy
|
|
25
26
|
Python module to query SQL databases and return numpy arrays, upload
|
|
26
27
|
tables and run join queries involving local arrays and the tables in the DB.
|
|
27
|
-
|
|
28
|
+
This module is optimized to be able to deal efficiently with query results with millions of rows.
|
|
29
|
+
The module only works with PostgreSQL, SQLite and DuckDB databases.
|
|
28
30
|
|
|
29
31
|
The full documentation is available [here](http://sqlutilpy.readthedocs.io/en/latest/)
|
|
30
32
|
|
|
@@ -36,10 +38,11 @@ To install the package you just need to do pip install.
|
|
|
36
38
|
```
|
|
37
39
|
pip install sqlutilpy
|
|
38
40
|
```
|
|
39
|
-
##
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
## Authentication
|
|
42
|
+
|
|
43
|
+
Throughout this readme, I will assume that the .pgpass file ( https://www.postgresql.org/docs/11/libpq-pgpass.html )
|
|
44
|
+
has been created with your login/password details for Postgresql. If that is not the case, all of the
|
|
45
|
+
commands given below will also need user='....' and password='...' options
|
|
43
46
|
|
|
44
47
|
## Connection information
|
|
45
48
|
|
|
@@ -50,6 +53,8 @@ of the connection.
|
|
|
50
53
|
|
|
51
54
|
|
|
52
55
|
## Querying the database and retrieving the results
|
|
56
|
+
|
|
57
|
+
This command will run the query and put the columns into variables ra,dec
|
|
53
58
|
```python
|
|
54
59
|
import sqlutilpy
|
|
55
60
|
ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
@@ -57,10 +62,11 @@ ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
|
57
62
|
db='THE_NAME_OF_MY_DB')
|
|
58
63
|
```
|
|
59
64
|
|
|
60
|
-
By default sqlutilpy.get executes the
|
|
61
|
-
results.
|
|
65
|
+
By default sqlutilpy.get executes the query and returns the tuple with
|
|
66
|
+
results. You can return the results as dictionary using asDict option.
|
|
62
67
|
|
|
63
68
|
## Uploading your arrays as column in a table
|
|
69
|
+
|
|
64
70
|
```python
|
|
65
71
|
x = np.arange(10)
|
|
66
72
|
y = x**.5
|
|
@@ -76,20 +82,28 @@ you could upload the arrays in the DB and run a query, but local_join function d
|
|
|
76
82
|
|
|
77
83
|
```python
|
|
78
84
|
myid = np.arange(10)
|
|
79
|
-
y =
|
|
85
|
+
y = np.random.uniform(size=10)
|
|
86
|
+
|
|
80
87
|
R=sqlutilpy.local_join('''select * from mytmptable as m,
|
|
81
|
-
somebigtable as s where s.id=m.myid order by m.myid''',
|
|
88
|
+
somebigtable as s where s.id=m.myid order by m.myid''',
|
|
89
|
+
'mytmptable',(myid, y),('myid','ycol'))
|
|
82
90
|
```
|
|
83
|
-
It executes a query as if you arrays where in a mytmptable. ( behind the scenes
|
|
84
|
-
it uploads the data to the db and runs a query)
|
|
85
91
|
|
|
92
|
+
It executes a query as if you arrays were in mytmptable. (behind the scenes
|
|
93
|
+
it uploads the data to the db and runs a query)
|
|
86
94
|
|
|
87
95
|
## Keeping the connection open.
|
|
88
96
|
|
|
89
|
-
Often it
|
|
97
|
+
Often it is beneficial to preserve an open connection to the database. You can do that if you first
|
|
90
98
|
obtain the connection using sqlutilpy.getConnection() and then provide it directly
|
|
91
99
|
to sqlutil.get() and friends using conn=conn argument
|
|
100
|
+
```python
|
|
101
|
+
conn = sqlutilpy.getConnection(db='mydb', user='meuser', password='something', host='hostname')
|
|
102
|
+
R= sqlutilpy.get('select 1', conn=conn)
|
|
103
|
+
R1= sqlutilpy.get('select 1', conn=conn)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
# How to cite the software
|
|
92
107
|
|
|
108
|
+
If you use this package, please cite it through zenodo https://doi.org/10.5281/zenodo.6867957
|
|
93
109
|
|
|
94
|
-
# How to cite it
|
|
95
|
-
If you use this, please cite it through zenodo https://doi.org/10.5281/zenodo.6867957
|
|
@@ -6,7 +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
|
-
|
|
9
|
+
This module is optimized to be able to deal efficiently with query results with millions of rows.
|
|
10
|
+
The module only works with PostgreSQL, SQLite and DuckDB databases.
|
|
10
11
|
|
|
11
12
|
The full documentation is available [here](http://sqlutilpy.readthedocs.io/en/latest/)
|
|
12
13
|
|
|
@@ -18,10 +19,11 @@ To install the package you just need to do pip install.
|
|
|
18
19
|
```
|
|
19
20
|
pip install sqlutilpy
|
|
20
21
|
```
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
## Authentication
|
|
23
|
+
|
|
24
|
+
Throughout this readme, I will assume that the .pgpass file ( https://www.postgresql.org/docs/11/libpq-pgpass.html )
|
|
25
|
+
has been created with your login/password details for Postgresql. If that is not the case, all of the
|
|
26
|
+
commands given below will also need user='....' and password='...' options
|
|
25
27
|
|
|
26
28
|
## Connection information
|
|
27
29
|
|
|
@@ -32,6 +34,8 @@ of the connection.
|
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
## Querying the database and retrieving the results
|
|
37
|
+
|
|
38
|
+
This command will run the query and put the columns into variables ra,dec
|
|
35
39
|
```python
|
|
36
40
|
import sqlutilpy
|
|
37
41
|
ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
@@ -39,10 +43,11 @@ ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
|
39
43
|
db='THE_NAME_OF_MY_DB')
|
|
40
44
|
```
|
|
41
45
|
|
|
42
|
-
By default sqlutilpy.get executes the
|
|
43
|
-
results.
|
|
46
|
+
By default sqlutilpy.get executes the query and returns the tuple with
|
|
47
|
+
results. You can return the results as dictionary using asDict option.
|
|
44
48
|
|
|
45
49
|
## Uploading your arrays as column in a table
|
|
50
|
+
|
|
46
51
|
```python
|
|
47
52
|
x = np.arange(10)
|
|
48
53
|
y = x**.5
|
|
@@ -58,20 +63,28 @@ you could upload the arrays in the DB and run a query, but local_join function d
|
|
|
58
63
|
|
|
59
64
|
```python
|
|
60
65
|
myid = np.arange(10)
|
|
61
|
-
y =
|
|
66
|
+
y = np.random.uniform(size=10)
|
|
67
|
+
|
|
62
68
|
R=sqlutilpy.local_join('''select * from mytmptable as m,
|
|
63
|
-
somebigtable as s where s.id=m.myid order by m.myid''',
|
|
69
|
+
somebigtable as s where s.id=m.myid order by m.myid''',
|
|
70
|
+
'mytmptable',(myid, y),('myid','ycol'))
|
|
64
71
|
```
|
|
65
|
-
It executes a query as if you arrays where in a mytmptable. ( behind the scenes
|
|
66
|
-
it uploads the data to the db and runs a query)
|
|
67
72
|
|
|
73
|
+
It executes a query as if you arrays were in mytmptable. (behind the scenes
|
|
74
|
+
it uploads the data to the db and runs a query)
|
|
68
75
|
|
|
69
76
|
## Keeping the connection open.
|
|
70
77
|
|
|
71
|
-
Often it
|
|
78
|
+
Often it is beneficial to preserve an open connection to the database. You can do that if you first
|
|
72
79
|
obtain the connection using sqlutilpy.getConnection() and then provide it directly
|
|
73
80
|
to sqlutil.get() and friends using conn=conn argument
|
|
81
|
+
```python
|
|
82
|
+
conn = sqlutilpy.getConnection(db='mydb', user='meuser', password='something', host='hostname')
|
|
83
|
+
R= sqlutilpy.get('select 1', conn=conn)
|
|
84
|
+
R1= sqlutilpy.get('select 1', conn=conn)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
# How to cite the software
|
|
74
88
|
|
|
89
|
+
If you use this package, please cite it through zenodo https://doi.org/10.5281/zenodo.6867957
|
|
75
90
|
|
|
76
|
-
# How to cite it
|
|
77
|
-
If you use this, please cite it through zenodo https://doi.org/10.5281/zenodo.6867957
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "sqlutilpy"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
description = "Database query code returning numpy arrays"
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "Sergey E. Koposov", email = "skoposov@ed.ac.uk"},
|
|
7
|
+
]
|
|
8
|
+
dependencies = [
|
|
9
|
+
"numpy",
|
|
10
|
+
"psycopg[binary]",
|
|
11
|
+
"numpydoc",
|
|
12
|
+
"numpy\n"
|
|
13
|
+
]
|
|
14
|
+
requires-python = ">=3.8"
|
|
15
|
+
readme = "README.md"
|
|
16
|
+
license = {text = "BSD"}
|
|
17
|
+
keywords = ["numpy postgresql query sql sqlite array"]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 3 - Alpha",
|
|
20
|
+
"License :: OSI Approved :: BSD License",
|
|
21
|
+
"Topic :: Utilities",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[build-system]
|
|
25
|
+
requires = ["setuptools", "wheel", "setuptools-git-versioning"]
|
|
26
|
+
build-backend = "setuptools.build_meta"
|
|
27
|
+
|
|
28
|
+
[tool.setuptools-git-versioning]
|
|
29
|
+
enabled = true
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/segasai/sqlutilpy"
|
|
33
|
+
|
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
from __future__ import print_function
|
|
4
4
|
import numpy
|
|
5
5
|
import numpy as np
|
|
6
|
-
import
|
|
6
|
+
import psycopg
|
|
7
7
|
import threading
|
|
8
8
|
import collections
|
|
9
9
|
import warnings
|
|
10
10
|
from numpy.core import numeric as sb
|
|
11
|
-
from select import select
|
|
12
|
-
from psycopg2.extensions import POLL_OK, POLL_READ, POLL_WRITE
|
|
13
11
|
|
|
14
12
|
try:
|
|
15
13
|
import astropy.table as atpy
|
|
@@ -22,7 +20,6 @@ except ImportError:
|
|
|
22
20
|
# pandas is not installed
|
|
23
21
|
pandas = None
|
|
24
22
|
|
|
25
|
-
from io import BytesIO as StringIO
|
|
26
23
|
import queue
|
|
27
24
|
|
|
28
25
|
_WAIT_SELECT_TIMEOUT = 10
|
|
@@ -37,31 +34,6 @@ class SqlUtilException(Exception):
|
|
|
37
34
|
pass
|
|
38
35
|
|
|
39
36
|
|
|
40
|
-
def __wait_select_inter(conn):
|
|
41
|
-
""" Make the queries interruptible by Ctrl-C
|
|
42
|
-
|
|
43
|
-
Taken from http://initd.org/psycopg/articles/2014/07/20/cancelling-postgresql-statements-python/ # noqa
|
|
44
|
-
"""
|
|
45
|
-
while True:
|
|
46
|
-
try:
|
|
47
|
-
state = conn.poll()
|
|
48
|
-
if state == POLL_OK:
|
|
49
|
-
break
|
|
50
|
-
elif state == POLL_READ:
|
|
51
|
-
select([conn.fileno()], [], [], _WAIT_SELECT_TIMEOUT)
|
|
52
|
-
elif state == POLL_WRITE:
|
|
53
|
-
select([], [conn.fileno()], [], _WAIT_SELECT_TIMEOUT)
|
|
54
|
-
else:
|
|
55
|
-
raise conn.OperationalError("bad state from poll: %s" % state)
|
|
56
|
-
except KeyboardInterrupt:
|
|
57
|
-
conn.cancel()
|
|
58
|
-
# the loop will be broken by a server error
|
|
59
|
-
continue
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
psycopg2.extensions.set_wait_callback(__wait_select_inter)
|
|
63
|
-
|
|
64
|
-
|
|
65
37
|
def getConnection(db=None,
|
|
66
38
|
driver=None,
|
|
67
39
|
user=None,
|
|
@@ -80,7 +52,7 @@ def getConnection(db=None,
|
|
|
80
52
|
The name of the database (in case of PostgreSQL) or filename in
|
|
81
53
|
case of sqlite db
|
|
82
54
|
driver : string
|
|
83
|
-
The db driver (either '
|
|
55
|
+
The db driver (either 'psycopg' or 'sqlite3')
|
|
84
56
|
user : string, optional
|
|
85
57
|
Username
|
|
86
58
|
password: string, optional
|
|
@@ -99,6 +71,10 @@ def getConnection(db=None,
|
|
|
99
71
|
|
|
100
72
|
"""
|
|
101
73
|
if driver == 'psycopg2':
|
|
74
|
+
warnings.warn(
|
|
75
|
+
'psycopg2 driver is not supported anymore using psycopg instead')
|
|
76
|
+
driver = 'psycopg'
|
|
77
|
+
if driver == 'psycopg':
|
|
102
78
|
conn_dict = dict()
|
|
103
79
|
if db is not None:
|
|
104
80
|
conn_dict['dbname'] = db
|
|
@@ -110,7 +86,7 @@ def getConnection(db=None,
|
|
|
110
86
|
conn_dict['user'] = user
|
|
111
87
|
if password is not None:
|
|
112
88
|
conn_dict['password'] = password
|
|
113
|
-
conn =
|
|
89
|
+
conn = psycopg.connect(**conn_dict)
|
|
114
90
|
elif driver == 'sqlite3':
|
|
115
91
|
import sqlite3
|
|
116
92
|
if timeout is None:
|
|
@@ -126,6 +102,10 @@ def getCursor(conn, driver=None, preamb=None, notNamed=False):
|
|
|
126
102
|
Retrieve the database cursor
|
|
127
103
|
"""
|
|
128
104
|
if driver == 'psycopg2':
|
|
105
|
+
warnings.warn(
|
|
106
|
+
'psycopg2 driver is not supported anymore using psycopg instead')
|
|
107
|
+
driver = 'psycopg'
|
|
108
|
+
if driver == 'psycopg':
|
|
129
109
|
cur = conn.cursor()
|
|
130
110
|
if preamb is not None:
|
|
131
111
|
cur.execute(preamb)
|
|
@@ -267,7 +247,7 @@ def __getDType(row, typeCodes, strLength):
|
|
|
267
247
|
def get(query,
|
|
268
248
|
params=None,
|
|
269
249
|
db="wsdb",
|
|
270
|
-
driver="
|
|
250
|
+
driver="psycopg",
|
|
271
251
|
user=None,
|
|
272
252
|
password=None,
|
|
273
253
|
host=None,
|
|
@@ -304,7 +284,7 @@ def get(query,
|
|
|
304
284
|
db : string
|
|
305
285
|
The name of the database
|
|
306
286
|
driver : string, optional
|
|
307
|
-
The sql driver to be used (
|
|
287
|
+
The sql driver to be used (psycopg or sqlite3)
|
|
308
288
|
user : string, optional
|
|
309
289
|
User name for the DB connection
|
|
310
290
|
password : string, optional
|
|
@@ -359,6 +339,11 @@ def get(query,
|
|
|
359
339
|
proc = None
|
|
360
340
|
colNames = []
|
|
361
341
|
if driver == 'psycopg2':
|
|
342
|
+
warnings.warn(
|
|
343
|
+
'psycopg2 driver is not supported anymore using psycopg instead'
|
|
344
|
+
)
|
|
345
|
+
driver = 'psycopg'
|
|
346
|
+
if driver == 'psycopg':
|
|
362
347
|
try:
|
|
363
348
|
while (True):
|
|
364
349
|
# Iterating over the cursor, retrieving batches of results
|
|
@@ -473,7 +458,7 @@ def get(query,
|
|
|
473
458
|
def execute(query,
|
|
474
459
|
params=None,
|
|
475
460
|
db='wsdb',
|
|
476
|
-
driver="
|
|
461
|
+
driver="psycopg",
|
|
477
462
|
user=None,
|
|
478
463
|
password=None,
|
|
479
464
|
host=None,
|
|
@@ -493,7 +478,7 @@ def execute(query,
|
|
|
493
478
|
db : string
|
|
494
479
|
Database name
|
|
495
480
|
driver : string
|
|
496
|
-
Driver for the DB connection ('
|
|
481
|
+
Driver for the DB connection ('psycopg' or 'sqlite3')
|
|
497
482
|
user : string, optional
|
|
498
483
|
user name for the DB connection
|
|
499
484
|
password : string, optional
|
|
@@ -542,7 +527,7 @@ def __create_schema(tableName, arrays, names, temp=False):
|
|
|
542
527
|
(np.uint64, 'bigint'), (np.int16, 'smallint'),
|
|
543
528
|
(np.uint8, 'smallint'), (np.int8, 'smallint'),
|
|
544
529
|
(np.float32, 'real'), (np.float64, 'double precision'),
|
|
545
|
-
(np.
|
|
530
|
+
(np.bytes_, 'varchar'), (np.str_, 'varchar'),
|
|
546
531
|
(np.bool_, 'boolean'), (np.datetime64, 'timestamp')])
|
|
547
532
|
if temp:
|
|
548
533
|
temp = 'temporary'
|
|
@@ -568,7 +553,7 @@ def __print_arrays(arrays, f, delimiter=' '):
|
|
|
568
553
|
format_dict = dict([(np.int32, '%d'), (np.int64, '%d'), (np.int16, '%d'),
|
|
569
554
|
(np.int8, '%d'), (np.uint8, '%d'),
|
|
570
555
|
(np.float32, '%.18e'), (np.float64, '%.18e'),
|
|
571
|
-
(np.
|
|
556
|
+
(np.bytes_, '%s'), (np.str_, '%s'),
|
|
572
557
|
(np.datetime64, '%s'), (np.bool_, '%d')])
|
|
573
558
|
fmts = []
|
|
574
559
|
array_mode = False
|
|
@@ -626,7 +611,7 @@ def upload(tableName,
|
|
|
626
611
|
arrays,
|
|
627
612
|
names=None,
|
|
628
613
|
db="wsdb",
|
|
629
|
-
driver="
|
|
614
|
+
driver="psycopg",
|
|
630
615
|
user=None,
|
|
631
616
|
password=None,
|
|
632
617
|
host=None,
|
|
@@ -653,7 +638,7 @@ def upload(tableName,
|
|
|
653
638
|
db: string
|
|
654
639
|
Databas name
|
|
655
640
|
driver: string
|
|
656
|
-
Python database driver "
|
|
641
|
+
Python database driver "psycopg",
|
|
657
642
|
user: string,
|
|
658
643
|
password: string
|
|
659
644
|
host: string
|
|
@@ -743,18 +728,18 @@ table/pandas/dictionary or provide a separate list of arrays and their names')
|
|
|
743
728
|
cur.execute(query1)
|
|
744
729
|
nsplit = 100000
|
|
745
730
|
N = len(arrays[0])
|
|
731
|
+
names = ','.join(names)
|
|
746
732
|
for i in range(0, N, nsplit):
|
|
747
|
-
f = StringIO()
|
|
748
|
-
__print_arrays([_[i:i + nsplit] for _ in arrays],
|
|
749
|
-
f,
|
|
750
|
-
delimiter=delimiter)
|
|
751
|
-
f.seek(0)
|
|
752
733
|
try:
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
734
|
+
with cur.copy(
|
|
735
|
+
f'''copy {tableName}({names}) from stdin with delimiter '{delimiter}' '''
|
|
736
|
+
) as copy:
|
|
737
|
+
__print_arrays([_[i:i + nsplit] for _ in arrays],
|
|
738
|
+
copy,
|
|
739
|
+
delimiter=delimiter)
|
|
740
|
+
|
|
756
741
|
finally:
|
|
757
|
-
|
|
742
|
+
pass
|
|
758
743
|
except BaseException:
|
|
759
744
|
failure_cleanup(conn, connSupplied)
|
|
760
745
|
raise
|
|
@@ -772,7 +757,7 @@ def local_join(query,
|
|
|
772
757
|
arrays,
|
|
773
758
|
names,
|
|
774
759
|
db=None,
|
|
775
|
-
driver="
|
|
760
|
+
driver="psycopg",
|
|
776
761
|
user=None,
|
|
777
762
|
password=None,
|
|
778
763
|
host=None,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.23.0'
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sqlutilpy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.23.0
|
|
4
4
|
Summary: Database query code returning numpy arrays
|
|
5
|
-
|
|
6
|
-
Author: Sergey Koposov
|
|
7
|
-
Author-email: skoposov@ed.ac.uk
|
|
5
|
+
Author-email: "Sergey E. Koposov" <skoposov@ed.ac.uk>
|
|
8
6
|
License: BSD
|
|
7
|
+
Project-URL: Homepage, https://github.com/segasai/sqlutilpy
|
|
9
8
|
Keywords: numpy postgresql query sql sqlite array
|
|
10
9
|
Classifier: Development Status :: 3 - Alpha
|
|
11
|
-
Classifier: Topic :: Utilities
|
|
12
10
|
Classifier: License :: OSI Approved :: BSD License
|
|
11
|
+
Classifier: Topic :: Utilities
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE.txt
|
|
15
15
|
Requires-Dist: numpy
|
|
16
|
-
Requires-Dist:
|
|
16
|
+
Requires-Dist: psycopg[binary]
|
|
17
17
|
Requires-Dist: numpydoc
|
|
18
|
+
Requires-Dist: numpy
|
|
18
19
|
|
|
19
20
|
[](https://github.com/segasai/sqlutilpy/actions)
|
|
20
21
|
[](http://sqlutilpy.readthedocs.io/en/latest/?badge=latest)
|
|
@@ -24,7 +25,8 @@ Requires-Dist: numpydoc
|
|
|
24
25
|
# sqlutilpy
|
|
25
26
|
Python module to query SQL databases and return numpy arrays, upload
|
|
26
27
|
tables and run join queries involving local arrays and the tables in the DB.
|
|
27
|
-
|
|
28
|
+
This module is optimized to be able to deal efficiently with query results with millions of rows.
|
|
29
|
+
The module only works with PostgreSQL, SQLite and DuckDB databases.
|
|
28
30
|
|
|
29
31
|
The full documentation is available [here](http://sqlutilpy.readthedocs.io/en/latest/)
|
|
30
32
|
|
|
@@ -36,10 +38,11 @@ To install the package you just need to do pip install.
|
|
|
36
38
|
```
|
|
37
39
|
pip install sqlutilpy
|
|
38
40
|
```
|
|
39
|
-
##
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
## Authentication
|
|
42
|
+
|
|
43
|
+
Throughout this readme, I will assume that the .pgpass file ( https://www.postgresql.org/docs/11/libpq-pgpass.html )
|
|
44
|
+
has been created with your login/password details for Postgresql. If that is not the case, all of the
|
|
45
|
+
commands given below will also need user='....' and password='...' options
|
|
43
46
|
|
|
44
47
|
## Connection information
|
|
45
48
|
|
|
@@ -50,6 +53,8 @@ of the connection.
|
|
|
50
53
|
|
|
51
54
|
|
|
52
55
|
## Querying the database and retrieving the results
|
|
56
|
+
|
|
57
|
+
This command will run the query and put the columns into variables ra,dec
|
|
53
58
|
```python
|
|
54
59
|
import sqlutilpy
|
|
55
60
|
ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
@@ -57,10 +62,11 @@ ra,dec = squtilpy.get('select ra,dec from mytable',
|
|
|
57
62
|
db='THE_NAME_OF_MY_DB')
|
|
58
63
|
```
|
|
59
64
|
|
|
60
|
-
By default sqlutilpy.get executes the
|
|
61
|
-
results.
|
|
65
|
+
By default sqlutilpy.get executes the query and returns the tuple with
|
|
66
|
+
results. You can return the results as dictionary using asDict option.
|
|
62
67
|
|
|
63
68
|
## Uploading your arrays as column in a table
|
|
69
|
+
|
|
64
70
|
```python
|
|
65
71
|
x = np.arange(10)
|
|
66
72
|
y = x**.5
|
|
@@ -76,20 +82,28 @@ you could upload the arrays in the DB and run a query, but local_join function d
|
|
|
76
82
|
|
|
77
83
|
```python
|
|
78
84
|
myid = np.arange(10)
|
|
79
|
-
y =
|
|
85
|
+
y = np.random.uniform(size=10)
|
|
86
|
+
|
|
80
87
|
R=sqlutilpy.local_join('''select * from mytmptable as m,
|
|
81
|
-
somebigtable as s where s.id=m.myid order by m.myid''',
|
|
88
|
+
somebigtable as s where s.id=m.myid order by m.myid''',
|
|
89
|
+
'mytmptable',(myid, y),('myid','ycol'))
|
|
82
90
|
```
|
|
83
|
-
It executes a query as if you arrays where in a mytmptable. ( behind the scenes
|
|
84
|
-
it uploads the data to the db and runs a query)
|
|
85
91
|
|
|
92
|
+
It executes a query as if you arrays were in mytmptable. (behind the scenes
|
|
93
|
+
it uploads the data to the db and runs a query)
|
|
86
94
|
|
|
87
95
|
## Keeping the connection open.
|
|
88
96
|
|
|
89
|
-
Often it
|
|
97
|
+
Often it is beneficial to preserve an open connection to the database. You can do that if you first
|
|
90
98
|
obtain the connection using sqlutilpy.getConnection() and then provide it directly
|
|
91
99
|
to sqlutil.get() and friends using conn=conn argument
|
|
100
|
+
```python
|
|
101
|
+
conn = sqlutilpy.getConnection(db='mydb', user='meuser', password='something', host='hostname')
|
|
102
|
+
R= sqlutilpy.get('select 1', conn=conn)
|
|
103
|
+
R1= sqlutilpy.get('select 1', conn=conn)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
# How to cite the software
|
|
92
107
|
|
|
108
|
+
If you use this package, please cite it through zenodo https://doi.org/10.5281/zenodo.6867957
|
|
93
109
|
|
|
94
|
-
# How to cite it
|
|
95
|
-
If you use this, please cite it through zenodo https://doi.org/10.5281/zenodo.6867957
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
LICENSE.txt
|
|
2
|
+
MANIFEST.in
|
|
3
|
+
README.md
|
|
4
|
+
pyproject.toml
|
|
5
|
+
src/sqlutilpy/__init__.py
|
|
6
|
+
src/sqlutilpy/sqlutil.py
|
|
7
|
+
src/sqlutilpy/version.py
|
|
8
|
+
src/sqlutilpy.egg-info/PKG-INFO
|
|
9
|
+
src/sqlutilpy.egg-info/SOURCES.txt
|
|
10
|
+
src/sqlutilpy.egg-info/dependency_links.txt
|
|
11
|
+
src/sqlutilpy.egg-info/requires.txt
|
|
12
|
+
src/sqlutilpy.egg-info/top_level.txt
|
|
13
|
+
tests/killer.py
|
|
14
|
+
tests/test_pg.py
|
|
15
|
+
tests/test_sqlite.py
|