sqlutilpy 0.22.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sqlutilpy
3
- Version: 0.22.0
3
+ Version: 0.23.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
@@ -9,12 +9,13 @@ Keywords: numpy postgresql query sql sqlite array
9
9
  Classifier: Development Status :: 3 - Alpha
10
10
  Classifier: License :: OSI Approved :: BSD License
11
11
  Classifier: Topic :: Utilities
12
- Requires-Python: >=3.6
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: psycopg2-binary
16
+ Requires-Dist: psycopg[binary]
17
17
  Requires-Dist: numpydoc
18
+ Requires-Dist: numpy
18
19
 
19
20
  [![Build Status](https://github.com/segasai/sqlutilpy/workflows/Testing/badge.svg)](https://github.com/segasai/sqlutilpy/actions)
20
21
  [![Documentation Status](https://readthedocs.org/projects/sqlutilpy/badge/?version=latest)](http://sqlutilpy.readthedocs.io/en/latest/?badge=latest)
@@ -7,10 +7,11 @@ authors = [
7
7
  ]
8
8
  dependencies = [
9
9
  "numpy",
10
- "psycopg2-binary",
10
+ "psycopg[binary]",
11
11
  "numpydoc",
12
+ "numpy\n"
12
13
  ]
13
- requires-python = ">=3.6"
14
+ requires-python = ">=3.8"
14
15
  readme = "README.md"
15
16
  license = {text = "BSD"}
16
17
  keywords = ["numpy postgresql query sql sqlite array"]
@@ -3,13 +3,11 @@
3
3
  from __future__ import print_function
4
4
  import numpy
5
5
  import numpy as np
6
- import psycopg2
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 'psycopg2' or 'sqlite3')
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 = psycopg2.connect(**conn_dict)
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="psycopg2",
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 (psycopg2 or sqlite3)
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="psycopg2",
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 ('psycopg2' or 'sqlite3')
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.string_, 'varchar'), (np.str_, 'varchar'),
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.string_, '%s'), (np.str_, '%s'),
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="psycopg2",
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 "psycopg2",
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
- thread = psycopg2.extensions.get_wait_callback()
754
- psycopg2.extensions.set_wait_callback(None)
755
- cur.copy_from(f, tableName, sep=delimiter, columns=names)
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
- psycopg2.extensions.set_wait_callback(thread)
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="psycopg2",
760
+ driver="psycopg",
776
761
  user=None,
777
762
  password=None,
778
763
  host=None,
@@ -0,0 +1 @@
1
+ __version__ = '0.23.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sqlutilpy
3
- Version: 0.22.0
3
+ Version: 0.23.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
@@ -9,12 +9,13 @@ Keywords: numpy postgresql query sql sqlite array
9
9
  Classifier: Development Status :: 3 - Alpha
10
10
  Classifier: License :: OSI Approved :: BSD License
11
11
  Classifier: Topic :: Utilities
12
- Requires-Python: >=3.6
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: psycopg2-binary
16
+ Requires-Dist: psycopg[binary]
17
17
  Requires-Dist: numpydoc
18
+ Requires-Dist: numpy
18
19
 
19
20
  [![Build Status](https://github.com/segasai/sqlutilpy/workflows/Testing/badge.svg)](https://github.com/segasai/sqlutilpy/actions)
20
21
  [![Documentation Status](https://readthedocs.org/projects/sqlutilpy/badge/?version=latest)](http://sqlutilpy.readthedocs.io/en/latest/?badge=latest)
@@ -0,0 +1,4 @@
1
+ numpy
2
+ psycopg[binary]
3
+ numpydoc
4
+ numpy
@@ -1,7 +1,7 @@
1
1
  import pytest
2
2
  import string
3
3
  import os
4
- import psycopg2
4
+ import psycopg
5
5
  import numpy as np
6
6
  import sqlutilpy as sqlutil
7
7
  import time
@@ -16,7 +16,7 @@ PG_PASS = os.environ['SQLUTIL_TEST_PG_PASS']
16
16
  def getrand(N, float=False):
17
17
  # simple deterministic pseudo-random number generator
18
18
  a, c = 1103515245, 12345
19
- m = 2 ^ 31
19
+ m = 2**31
20
20
  arr = np.zeros(N)
21
21
  arr[0] = 1
22
22
  for i in range(1, N):
@@ -37,8 +37,8 @@ def getconn():
37
37
 
38
38
  @pytest.fixture
39
39
  def setup():
40
- conn = psycopg2.connect('dbname=%s user=%s host=%s password=%s' %
41
- (PG_DB, PG_USER, PG_HOST, PG_PASS))
40
+ conn = psycopg.connect('dbname=%s user=%s host=%s password=%s' %
41
+ (PG_DB, PG_USER, PG_HOST, PG_PASS))
42
42
  cur = conn.cursor()
43
43
  cur.execute('''
44
44
  create unlogged table sqlutil_test (sicol smallint, intcol int,
@@ -123,11 +123,14 @@ def test_nocommit(setup):
123
123
 
124
124
  def test_local_join(setup):
125
125
  kw, conn = setup
126
+ N = 1000
127
+ rands = np.random.uniform(size=N)
126
128
  R, = sqlutil.local_join(
127
129
  '''
128
- select s.sicol from sqlutil_test as s, mytab as m
129
- where s.sicol = m.id''', 'mytab', [np.arange(10)], ['id'], **kw)
130
- assert (len(R) == 1)
130
+ select xf from sqlutil_test as s, mytab as m
131
+ where s.sicol = m.id''', 'mytab', [np.arange(N), rands], ['id', 'xf'],
132
+ **kw)
133
+ assert (len(R) == 2)
131
134
 
132
135
 
133
136
  def test_big(setup):
@@ -392,10 +395,27 @@ def test_upload(setup):
392
395
  # try the weird names
393
396
  sqlutil.upload(mytab1, (xi16, xi32, xi64, xf32, xf64, xbool),
394
397
  ('xi 16', 'xi(32)', 'xi[64]', 'xf32', 'xf64', 'xbool'),
395
- **kw)
398
+ temp=True,
399
+ conn=conn)
396
400
  yi16, yi32, yi64, yf32, yf64, ybool = sqlutil.get(
397
401
  '''select xi_16,xi_32_,xi_64_,xf32,xf64,xbool from %s''' % (mytab1),
398
- **kw)
402
+ conn=conn)
403
+
404
+
405
+ def test_upload_big(setup):
406
+ kw, conn = setup
407
+ mytab = 'sqlutil_test_tab_big'
408
+ nrows = 1_000_000
409
+ xi = np.arange(nrows, dtype=np.int32)
410
+ xf = getrand(nrows, True)
411
+ sqlutil.upload(mytab, (xi, xf), ('xi', 'xf'), **kw)
412
+ yi, yf = sqlutil.get('''select xi,xf from %s order by xi''' % (mytab),
413
+ **kw)
414
+ try:
415
+ assert ((xi == yi).all())
416
+ assert (np.allclose(xf, yf))
417
+ finally:
418
+ sqlutil.execute('drop table %s' % mytab, **kw)
399
419
 
400
420
 
401
421
  def test_upload_array(setup):
@@ -1,12 +1,7 @@
1
1
  import pytest
2
- import string
3
2
  import os
4
- import psycopg2
5
- import numpy as np
6
3
  import sqlutilpy as sqlutil
7
4
  import sqlite3
8
- import time
9
- import killer
10
5
 
11
6
 
12
7
  @pytest.fixture()
@@ -1 +0,0 @@
1
- __version__ = '0.22.0'
@@ -1,3 +0,0 @@
1
- numpy
2
- psycopg2-binary
3
- numpydoc
File without changes
File without changes
File without changes
File without changes
File without changes