sqlutilpy 0.20.0__tar.gz → 0.22.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.
@@ -1,17 +1,20 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sqlutilpy
3
- Version: 0.20.0
3
+ Version: 0.22.0
4
4
  Summary: Database query code returning numpy arrays
5
- Home-page: https://github.com/segasai/sqlutilpy
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.6
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE.txt
15
+ Requires-Dist: numpy
16
+ Requires-Dist: psycopg2-binary
17
+ Requires-Dist: numpydoc
15
18
 
16
19
  [![Build Status](https://github.com/segasai/sqlutilpy/workflows/Testing/badge.svg)](https://github.com/segasai/sqlutilpy/actions)
17
20
  [![Documentation Status](https://readthedocs.org/projects/sqlutilpy/badge/?version=latest)](http://sqlutilpy.readthedocs.io/en/latest/?badge=latest)
@@ -21,7 +24,8 @@ License-File: LICENSE.txt
21
24
  # sqlutilpy
22
25
  Python module to query SQL databases and return numpy arrays, upload
23
26
  tables and run join queries involving local arrays and the tables in the DB.
24
- The module only works with PostgreSQL and SQLite databases.
27
+ This module is optimized to be able to deal efficiently with query results with millions of rows.
28
+ The module only works with PostgreSQL, SQLite and DuckDB databases.
25
29
 
26
30
  The full documentation is available [here](http://sqlutilpy.readthedocs.io/en/latest/)
27
31
 
@@ -33,10 +37,11 @@ To install the package you just need to do pip install.
33
37
  ```
34
38
  pip install sqlutilpy
35
39
  ```
36
- ## Authentification
37
- Throughout this readme, I'll assume that the .pgpass file ( https://www.postgresql.org/docs/11/libpq-pgpass.html )
38
- has been created with the login/password details for Postgresql. If that is not the case, all of the
39
- commands given above will also need user='....' and password='...' options
40
+ ## Authentication
41
+
42
+ Throughout this readme, I will assume that the .pgpass file ( https://www.postgresql.org/docs/11/libpq-pgpass.html )
43
+ has been created with your login/password details for Postgresql. If that is not the case, all of the
44
+ commands given below will also need user='....' and password='...' options
40
45
 
41
46
  ## Connection information
42
47
 
@@ -47,6 +52,8 @@ of the connection.
47
52
 
48
53
 
49
54
  ## Querying the database and retrieving the results
55
+
56
+ This command will run the query and put the columns into variables ra,dec
50
57
  ```python
51
58
  import sqlutilpy
52
59
  ra,dec = squtilpy.get('select ra,dec from mytable',
@@ -54,10 +61,11 @@ ra,dec = squtilpy.get('select ra,dec from mytable',
54
61
  db='THE_NAME_OF_MY_DB')
55
62
  ```
56
63
 
57
- By default sqlutilpy.get executes the result and returns the tuple of
58
- results. But you can return the results as dictionary using asDict option.
64
+ By default sqlutilpy.get executes the query and returns the tuple with
65
+ results. You can return the results as dictionary using asDict option.
59
66
 
60
67
  ## Uploading your arrays as column in a table
68
+
61
69
  ```python
62
70
  x = np.arange(10)
63
71
  y = x**.5
@@ -73,20 +81,28 @@ you could upload the arrays in the DB and run a query, but local_join function d
73
81
 
74
82
  ```python
75
83
  myid = np.arange(10)
76
- y = x**.5
84
+ y = np.random.uniform(size=10)
85
+
77
86
  R=sqlutilpy.local_join('''select * from mytmptable as m,
78
- somebigtable as s where s.id=m.myid order by m.myid''', 'mytmptable',(x,y),('myid','ycol'))
87
+ somebigtable as s where s.id=m.myid order by m.myid''',
88
+ 'mytmptable',(myid, y),('myid','ycol'))
79
89
  ```
80
- It executes a query as if you arrays where in a mytmptable. ( behind the scenes
81
- it uploads the data to the db and runs a query)
82
90
 
91
+ It executes a query as if you arrays were in mytmptable. (behind the scenes
92
+ it uploads the data to the db and runs a query)
83
93
 
84
94
  ## Keeping the connection open.
85
95
 
86
- Often it's benefitial to preserve an open connection. You can do that if you first
96
+ Often it is beneficial to preserve an open connection to the database. You can do that if you first
87
97
  obtain the connection using sqlutilpy.getConnection() and then provide it directly
88
98
  to sqlutil.get() and friends using conn=conn argument
99
+ ```python
100
+ conn = sqlutilpy.getConnection(db='mydb', user='meuser', password='something', host='hostname')
101
+ R= sqlutilpy.get('select 1', conn=conn)
102
+ R1= sqlutilpy.get('select 1', conn=conn)
103
+ ```
104
+
105
+ # How to cite the software
89
106
 
107
+ If you use this package, please cite it through zenodo https://doi.org/10.5281/zenodo.6867957
90
108
 
91
- # How to cite it
92
- 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
- The module only works with PostgreSQL and SQLite databases.
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
- ## Authentification
22
- Throughout this readme, I'll assume that the .pgpass file ( https://www.postgresql.org/docs/11/libpq-pgpass.html )
23
- has been created with the login/password details for Postgresql. If that is not the case, all of the
24
- commands given above will also need user='....' and password='...' options
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 result and returns the tuple of
43
- results. But you can return the results as dictionary using asDict option.
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 = x**.5
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''', 'mytmptable',(x,y),('myid','ycol'))
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's benefitial to preserve an open connection. You can do that if you first
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,32 @@
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
+ "psycopg2-binary",
11
+ "numpydoc",
12
+ ]
13
+ requires-python = ">=3.6"
14
+ readme = "README.md"
15
+ license = {text = "BSD"}
16
+ keywords = ["numpy postgresql query sql sqlite array"]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "License :: OSI Approved :: BSD License",
20
+ "Topic :: Utilities",
21
+ ]
22
+
23
+ [build-system]
24
+ requires = ["setuptools", "wheel", "setuptools-git-versioning"]
25
+ build-backend = "setuptools.build_meta"
26
+
27
+ [tool.setuptools-git-versioning]
28
+ enabled = true
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/segasai/sqlutilpy"
32
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -141,6 +141,12 @@ def getCursor(conn, driver=None, preamb=None, notNamed=False):
141
141
  cur = conn.cursor()
142
142
  if preamb is not None:
143
143
  cur.execute(preamb)
144
+ elif driver == 'duckdb':
145
+ cur = conn.cursor()
146
+ if preamb is not None:
147
+ cur.execute(preamb)
148
+ else:
149
+ raise SqlUtilException('unrecognized driver')
144
150
  return cur
145
151
 
146
152
 
@@ -224,7 +230,7 @@ def __getDType(row, typeCodes, strLength):
224
230
  1022: 'f8',
225
231
  1700: 'f8', # numeric
226
232
  1114: '<M8[us]', # timestamp
227
- 1082: '<M8[us]', # date
233
+ 1082: '<M8[us]', # date
228
234
  25: '|U%d',
229
235
  1042: '|U%d', # character()
230
236
  1043: '|U%d' # varchar
@@ -428,6 +434,13 @@ def get(query,
428
434
  res = numpy.core.records.array(tups)
429
435
  else:
430
436
  return [[]] * len(cur.description)
437
+ elif driver == 'duckdb':
438
+ tups = cur.fetchall()
439
+ colNames = [_tmp[0] for _tmp in cur.description]
440
+ if len(tups) > 0:
441
+ res = numpy.core.records.array(tups)
442
+ else:
443
+ return [[]] * len(cur.description)
431
444
 
432
445
  res = [res[tmp] for tmp in res.dtype.names]
433
446
 
@@ -527,10 +540,10 @@ def execute(query,
527
540
  def __create_schema(tableName, arrays, names, temp=False):
528
541
  hash = dict([(np.int32, 'integer'), (np.int64, 'bigint'),
529
542
  (np.uint64, 'bigint'), (np.int16, 'smallint'),
530
- (np.uint8, 'bigint'), (np.float32, 'real'),
531
- (np.float64, 'double precision'), (np.string_, 'varchar'),
532
- (np.str_, 'varchar'), (np.bool_, 'boolean'),
533
- (np.datetime64, 'timestamp')])
543
+ (np.uint8, 'smallint'), (np.int8, 'smallint'),
544
+ (np.float32, 'real'), (np.float64, 'double precision'),
545
+ (np.string_, 'varchar'), (np.str_, 'varchar'),
546
+ (np.bool_, 'boolean'), (np.datetime64, 'timestamp')])
534
547
  if temp:
535
548
  temp = 'temporary'
536
549
  else:
@@ -538,7 +551,13 @@ def __create_schema(tableName, arrays, names, temp=False):
538
551
  outp = 'create %s table %s ' % (temp, tableName)
539
552
  outp1 = []
540
553
  for arr, name in zip(arrays, names):
541
- outp1.append('"' + name + '" ' + hash[arr.dtype.type])
554
+ curtyp = arr.dtype.type
555
+ if curtyp == np.object_:
556
+ # array
557
+ curotyp = hash[arr[0].dtype.type] + '[]'
558
+ else:
559
+ curotyp = hash[arr.dtype.type]
560
+ outp1.append(f'"{name}" {curotyp}')
542
561
  return outp + '(' + ','.join(outp1) + ')'
543
562
 
544
563
 
@@ -547,13 +566,48 @@ def __print_arrays(arrays, f, delimiter=' '):
547
566
  print the input arrays into the open file separated by a delimiter
548
567
  """
549
568
  format_dict = dict([(np.int32, '%d'), (np.int64, '%d'), (np.int16, '%d'),
550
- (np.uint8, '%d'), (np.float32, '%.18e'),
551
- (np.float64, '%.18e'), (np.string_, '%s'),
552
- (np.str_, '%s'), (np.datetime64, '%s'),
553
- (np.bool_, '%d')])
554
- fmt = [format_dict[x.dtype.type] for x in arrays]
569
+ (np.int8, '%d'), (np.uint8, '%d'),
570
+ (np.float32, '%.18e'), (np.float64, '%.18e'),
571
+ (np.string_, '%s'), (np.str_, '%s'),
572
+ (np.datetime64, '%s'), (np.bool_, '%d')])
573
+ fmts = []
574
+ array_mode = False
575
+ names = []
576
+ for i, x in enumerate(arrays):
577
+ names.append('f%d' % i)
578
+ if x.dtype.type in format_dict:
579
+ fmts.append(format_dict[x.dtype.type])
580
+ else:
581
+ if x.dtype.type == np.object_:
582
+ array_mode = True
583
+ fmts.append(None)
584
+ else:
585
+ raise RuntimeError(
586
+ 'Unsupported column type %s. Please report' %
587
+ (x.dtype.type))
555
588
  recarr = np.rec.fromarrays(arrays)
556
- np.savetxt(f, recarr, fmt=fmt, delimiter=delimiter)
589
+ if not array_mode:
590
+ np.savetxt(f, recarr, fmt=fmts, delimiter=delimiter)
591
+ else:
592
+ # this is really slow
593
+ for row in recarr:
594
+ for i, field in enumerate(names):
595
+ if i != 0:
596
+ f.write(delimiter.encode())
597
+ if fmts[i] is None:
598
+ curstr = np.array2string(
599
+ row[field],
600
+ max_line_width=np.inf,
601
+ threshold=None,
602
+ separator=',',
603
+ formatter={'all': lambda x: str(x)})
604
+ # formatter is needed because otherwise there is
605
+ # whitespace padding
606
+ curstr = '{' + curstr[1:-1] + '}'
607
+ f.write(curstr.encode())
608
+ else:
609
+ f.write(str(row[field]).encode())
610
+ f.write(b'\n')
557
611
 
558
612
 
559
613
  def failure_cleanup(conn, connSupplied):
@@ -659,6 +713,9 @@ def upload(tableName,
659
713
  table/pandas/dictionary or provide a separate list of arrays and their names')
660
714
 
661
715
  arrays = [np.asarray(_) for _ in arrays]
716
+ if len(arrays) != len(names):
717
+ raise RuntimeError('The column names list must have the same '
718
+ 'length as array list')
662
719
  repl_char = {
663
720
  ' ': '_',
664
721
  '-': '_',
@@ -0,0 +1 @@
1
+ __version__ = '0.22.0'
@@ -1,17 +1,20 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sqlutilpy
3
- Version: 0.20.0
3
+ Version: 0.22.0
4
4
  Summary: Database query code returning numpy arrays
5
- Home-page: https://github.com/segasai/sqlutilpy
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.6
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE.txt
15
+ Requires-Dist: numpy
16
+ Requires-Dist: psycopg2-binary
17
+ Requires-Dist: numpydoc
15
18
 
16
19
  [![Build Status](https://github.com/segasai/sqlutilpy/workflows/Testing/badge.svg)](https://github.com/segasai/sqlutilpy/actions)
17
20
  [![Documentation Status](https://readthedocs.org/projects/sqlutilpy/badge/?version=latest)](http://sqlutilpy.readthedocs.io/en/latest/?badge=latest)
@@ -21,7 +24,8 @@ License-File: LICENSE.txt
21
24
  # sqlutilpy
22
25
  Python module to query SQL databases and return numpy arrays, upload
23
26
  tables and run join queries involving local arrays and the tables in the DB.
24
- The module only works with PostgreSQL and SQLite databases.
27
+ This module is optimized to be able to deal efficiently with query results with millions of rows.
28
+ The module only works with PostgreSQL, SQLite and DuckDB databases.
25
29
 
26
30
  The full documentation is available [here](http://sqlutilpy.readthedocs.io/en/latest/)
27
31
 
@@ -33,10 +37,11 @@ To install the package you just need to do pip install.
33
37
  ```
34
38
  pip install sqlutilpy
35
39
  ```
36
- ## Authentification
37
- Throughout this readme, I'll assume that the .pgpass file ( https://www.postgresql.org/docs/11/libpq-pgpass.html )
38
- has been created with the login/password details for Postgresql. If that is not the case, all of the
39
- commands given above will also need user='....' and password='...' options
40
+ ## Authentication
41
+
42
+ Throughout this readme, I will assume that the .pgpass file ( https://www.postgresql.org/docs/11/libpq-pgpass.html )
43
+ has been created with your login/password details for Postgresql. If that is not the case, all of the
44
+ commands given below will also need user='....' and password='...' options
40
45
 
41
46
  ## Connection information
42
47
 
@@ -47,6 +52,8 @@ of the connection.
47
52
 
48
53
 
49
54
  ## Querying the database and retrieving the results
55
+
56
+ This command will run the query and put the columns into variables ra,dec
50
57
  ```python
51
58
  import sqlutilpy
52
59
  ra,dec = squtilpy.get('select ra,dec from mytable',
@@ -54,10 +61,11 @@ ra,dec = squtilpy.get('select ra,dec from mytable',
54
61
  db='THE_NAME_OF_MY_DB')
55
62
  ```
56
63
 
57
- By default sqlutilpy.get executes the result and returns the tuple of
58
- results. But you can return the results as dictionary using asDict option.
64
+ By default sqlutilpy.get executes the query and returns the tuple with
65
+ results. You can return the results as dictionary using asDict option.
59
66
 
60
67
  ## Uploading your arrays as column in a table
68
+
61
69
  ```python
62
70
  x = np.arange(10)
63
71
  y = x**.5
@@ -73,20 +81,28 @@ you could upload the arrays in the DB and run a query, but local_join function d
73
81
 
74
82
  ```python
75
83
  myid = np.arange(10)
76
- y = x**.5
84
+ y = np.random.uniform(size=10)
85
+
77
86
  R=sqlutilpy.local_join('''select * from mytmptable as m,
78
- somebigtable as s where s.id=m.myid order by m.myid''', 'mytmptable',(x,y),('myid','ycol'))
87
+ somebigtable as s where s.id=m.myid order by m.myid''',
88
+ 'mytmptable',(myid, y),('myid','ycol'))
79
89
  ```
80
- It executes a query as if you arrays where in a mytmptable. ( behind the scenes
81
- it uploads the data to the db and runs a query)
82
90
 
91
+ It executes a query as if you arrays were in mytmptable. (behind the scenes
92
+ it uploads the data to the db and runs a query)
83
93
 
84
94
  ## Keeping the connection open.
85
95
 
86
- Often it's benefitial to preserve an open connection. You can do that if you first
96
+ Often it is beneficial to preserve an open connection to the database. You can do that if you first
87
97
  obtain the connection using sqlutilpy.getConnection() and then provide it directly
88
98
  to sqlutil.get() and friends using conn=conn argument
99
+ ```python
100
+ conn = sqlutilpy.getConnection(db='mydb', user='meuser', password='something', host='hostname')
101
+ R= sqlutilpy.get('select 1', conn=conn)
102
+ R1= sqlutilpy.get('select 1', conn=conn)
103
+ ```
104
+
105
+ # How to cite the software
89
106
 
107
+ If you use this package, please cite it through zenodo https://doi.org/10.5281/zenodo.6867957
90
108
 
91
- # How to cite it
92
- 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