singlestoredb 1.2.0__cp38-abi3-win_amd64.whl → 1.3.0__cp38-abi3-win_amd64.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.

Potentially problematic release.


This version of singlestoredb might be problematic. Click here for more details.

_singlestoredb_accel.pyd CHANGED
Binary file
singlestoredb/__init__.py CHANGED
@@ -13,7 +13,7 @@ Examples
13
13
 
14
14
  """
15
15
 
16
- __version__ = '1.2.0'
16
+ __version__ = '1.3.0'
17
17
 
18
18
  from typing import Any
19
19
 
@@ -2,7 +2,10 @@
2
2
  """SingleStoreDB connections and cursors."""
3
3
  import abc
4
4
  import inspect
5
+ import io
6
+ import queue
5
7
  import re
8
+ import sys
6
9
  import warnings
7
10
  import weakref
8
11
  from collections.abc import Mapping
@@ -33,6 +36,11 @@ from .config import get_option
33
36
  from .utils.results import Description
34
37
  from .utils.results import Result
35
38
 
39
+ if sys.version_info < (3, 10):
40
+ InfileQueue = queue.Queue
41
+ else:
42
+ InfileQueue = queue.Queue[Union[bytes, str]]
43
+
36
44
 
37
45
  # DB-API settings
38
46
  apilevel = '2.0'
@@ -496,6 +504,14 @@ class Cursor(metaclass=abc.ABCMeta):
496
504
  def execute(
497
505
  self, query: str,
498
506
  args: Optional[Union[Sequence[Any], Dict[str, Any], Any]] = None,
507
+ infile_stream: Optional[ # type: ignore
508
+ Union[
509
+ io.RawIOBase,
510
+ io.TextIOBase,
511
+ Iterator[Union[bytes, str]],
512
+ InfileQueue,
513
+ ]
514
+ ] = None,
499
515
  ) -> int:
500
516
  """
501
517
  Execute a SQL statement.
@@ -510,6 +526,8 @@ class Cursor(metaclass=abc.ABCMeta):
510
526
  The SQL statement to execute
511
527
  args : Sequence or dict, optional
512
528
  Parameters to substitute into the SQL code
529
+ infile_stream : io.RawIOBase or io.TextIOBase or Iterator[bytes|str], optional
530
+ Data stream for ``LOCAL INFILE`` statement
513
531
 
514
532
  Examples
515
533
  --------
@@ -1339,7 +1357,8 @@ def connect(
1339
1357
  autocommit : bool, optional
1340
1358
  Enable autocommits
1341
1359
  results_type : str, optional
1342
- The form of the query results: tuples, namedtuples, dicts
1360
+ The form of the query results: tuples, namedtuples, dicts,
1361
+ numpy, polars, pandas, arrow
1343
1362
  results_format : str, optional
1344
1363
  Deprecated. This option has been renamed to results_type.
1345
1364
  program_name : str, optional
@@ -3,6 +3,7 @@
3
3
  import datetime
4
4
  import decimal
5
5
  import functools
6
+ import io
6
7
  import json
7
8
  import math
8
9
  import os
@@ -420,6 +421,14 @@ class Cursor(connection.Cursor):
420
421
  def execute(
421
422
  self, query: str,
422
423
  args: Optional[Union[Sequence[Any], Dict[str, Any]]] = None,
424
+ infile_stream: Optional[ # type: ignore
425
+ Union[
426
+ io.RawIOBase,
427
+ io.TextIOBase,
428
+ Iterable[Union[bytes, str]],
429
+ connection.InfileQueue,
430
+ ]
431
+ ] = None,
423
432
  ) -> int:
424
433
  """
425
434
  Execute a SQL statement.
@@ -432,7 +441,7 @@ class Cursor(connection.Cursor):
432
441
  Parameters to substitute into the SQL code
433
442
 
434
443
  """
435
- return self._execute(query, args)
444
+ return self._execute(query, args, infile_stream=infile_stream)
436
445
 
437
446
  def _validate_param_subs(
438
447
  self, query: str,
@@ -496,6 +505,14 @@ class Cursor(connection.Cursor):
496
505
  self, oper: str,
497
506
  params: Optional[Union[Sequence[Any], Dict[str, Any]]] = None,
498
507
  is_callproc: bool = False,
508
+ infile_stream: Optional[ # type: ignore
509
+ Union[
510
+ io.RawIOBase,
511
+ io.TextIOBase,
512
+ Iterable[Union[bytes, str]],
513
+ connection.InfileQueue,
514
+ ]
515
+ ] = None,
499
516
  ) -> int:
500
517
  self._descriptions = []
501
518
  self._schemas = []
@@ -5,12 +5,15 @@
5
5
  # https://dev.mysql.com/doc/refman/5.5/en/error-handling.html
6
6
  import errno
7
7
  import functools
8
+ import io
8
9
  import os
10
+ import queue
9
11
  import socket
10
12
  import struct
11
13
  import sys
12
14
  import traceback
13
15
  import warnings
16
+ from typing import Iterable
14
17
 
15
18
  try:
16
19
  import _singlestoredb_accel
@@ -353,6 +356,7 @@ class Connection(BaseConnection):
353
356
  )
354
357
 
355
358
  self._local_infile = bool(local_infile)
359
+ self._local_infile_stream = None
356
360
  if self._local_infile:
357
361
  client_flag |= CLIENT.LOCAL_FILES
358
362
  if multi_statements:
@@ -843,7 +847,7 @@ class Connection(BaseConnection):
843
847
  return self.cursorclass(self)
844
848
 
845
849
  # The following methods are INTERNAL USE ONLY (called from Cursor)
846
- def query(self, sql, unbuffered=False):
850
+ def query(self, sql, unbuffered=False, infile_stream=None):
847
851
  """
848
852
  Run a query on the server.
849
853
 
@@ -859,8 +863,10 @@ class Connection(BaseConnection):
859
863
  else:
860
864
  if isinstance(sql, str):
861
865
  sql = sql.encode(self.encoding, 'surrogateescape')
866
+ self._local_infile_stream = infile_stream
862
867
  self._execute_command(COMMAND.COM_QUERY, sql)
863
868
  self._affected_rows = self._read_query_result(unbuffered=unbuffered)
869
+ self._local_infile_stream = None
864
870
  return self._affected_rows
865
871
 
866
872
  def next_result(self, unbuffered=False):
@@ -1871,24 +1877,82 @@ class LoadLocalFile:
1871
1877
  def send_data(self):
1872
1878
  """Send data packets from the local file to the server"""
1873
1879
  if not self.connection._sock:
1874
- raise err.InterfaceError(0, '')
1880
+ raise err.InterfaceError(0, 'Connection is closed')
1881
+
1875
1882
  conn = self.connection
1883
+ infile = conn._local_infile_stream
1884
+
1885
+ # 16KB is efficient enough
1886
+ packet_size = min(conn.max_allowed_packet, 16 * 1024)
1876
1887
 
1877
1888
  try:
1878
- with open(self.filename, 'rb') as open_file:
1879
- packet_size = min(
1880
- conn.max_allowed_packet, 16 * 1024,
1881
- ) # 16KB is efficient enough
1882
- while True:
1883
- chunk = open_file.read(packet_size)
1884
- if not chunk:
1885
- break
1886
- conn.write_packet(chunk)
1887
- except OSError:
1888
- raise err.OperationalError(
1889
- ER.FILE_NOT_FOUND,
1890
- f"Can't find file '{self.filename}'",
1891
- )
1889
+
1890
+ if self.filename in [':stream:', b':stream:']:
1891
+
1892
+ if infile is None:
1893
+ raise err.OperationalError(
1894
+ ER.FILE_NOT_FOUND,
1895
+ ':stream: specified for LOCAL INFILE, but no stream was supplied',
1896
+ )
1897
+
1898
+ # Binary IO
1899
+ elif isinstance(infile, io.RawIOBase):
1900
+ while True:
1901
+ chunk = infile.read(packet_size)
1902
+ if not chunk:
1903
+ break
1904
+ conn.write_packet(chunk)
1905
+
1906
+ # Text IO
1907
+ elif isinstance(infile, io.TextIOBase):
1908
+ while True:
1909
+ chunk = infile.read(packet_size)
1910
+ if not chunk:
1911
+ break
1912
+ conn.write_packet(chunk.encode('utf8'))
1913
+
1914
+ # Iterable of bytes or str
1915
+ elif isinstance(infile, Iterable):
1916
+ for chunk in infile:
1917
+ if not chunk:
1918
+ continue
1919
+ if isinstance(chunk, str):
1920
+ conn.write_packet(chunk.encode('utf8'))
1921
+ else:
1922
+ conn.write_packet(chunk)
1923
+
1924
+ # Queue (empty value ends the iteration)
1925
+ elif isinstance(infile, queue.Queue):
1926
+ while True:
1927
+ chunk = infile.get()
1928
+ if not chunk:
1929
+ break
1930
+ if isinstance(chunk, str):
1931
+ conn.write_packet(chunk.encode('utf8'))
1932
+ else:
1933
+ conn.write_packet(chunk)
1934
+
1935
+ else:
1936
+ raise err.OperationalError(
1937
+ ER.FILE_NOT_FOUND,
1938
+ ':stream: specified for LOCAL INFILE, ' +
1939
+ f'but stream type is unrecognized: {infile}',
1940
+ )
1941
+
1942
+ else:
1943
+ try:
1944
+ with open(self.filename, 'rb') as open_file:
1945
+ while True:
1946
+ chunk = open_file.read(packet_size)
1947
+ if not chunk:
1948
+ break
1949
+ conn.write_packet(chunk)
1950
+ except OSError:
1951
+ raise err.OperationalError(
1952
+ ER.FILE_NOT_FOUND,
1953
+ f"Can't find file '{self.filename!s}'",
1954
+ )
1955
+
1892
1956
  finally:
1893
1957
  if not conn._closed:
1894
1958
  # send the empty packet to signify we are done sending data
@@ -178,7 +178,7 @@ class Cursor(BaseCursor):
178
178
 
179
179
  return query
180
180
 
181
- def execute(self, query, args=None):
181
+ def execute(self, query, args=None, infile_stream=None):
182
182
  """
183
183
  Execute a query.
184
184
 
@@ -192,6 +192,8 @@ class Cursor(BaseCursor):
192
192
  Query to execute.
193
193
  args : Sequence[Any] or Dict[str, Any] or Any, optional
194
194
  Parameters used with query. (optional)
195
+ infile_stream : io.BytesIO or Iterator[bytes], optional
196
+ Data stream for ``LOCAL INFILE`` statements
195
197
 
196
198
  Returns
197
199
  -------
@@ -205,7 +207,7 @@ class Cursor(BaseCursor):
205
207
 
206
208
  query = self.mogrify(query, args)
207
209
 
208
- result = self._query(query)
210
+ result = self._query(query, infile_stream=infile_stream)
209
211
  self._executed = query
210
212
  return result
211
213
 
@@ -387,10 +389,10 @@ class Cursor(BaseCursor):
387
389
  raise IndexError('out of range')
388
390
  self._rownumber = r
389
391
 
390
- def _query(self, q):
392
+ def _query(self, q, infile_stream=None):
391
393
  conn = self._get_db()
392
394
  self._clear_result()
393
- conn.query(q)
395
+ conn.query(q, infile_stream=infile_stream)
394
396
  self._do_get_result()
395
397
  return self.rowcount
396
398
 
@@ -680,10 +682,10 @@ class SSCursor(Cursor):
680
682
 
681
683
  __del__ = close
682
684
 
683
- def _query(self, q):
685
+ def _query(self, q, infile_stream=None):
684
686
  conn = self._get_db()
685
687
  self._clear_result()
686
- conn.query(q, unbuffered=True)
688
+ conn.query(q, unbuffered=True, infile_stream=infile_stream)
687
689
  self._do_get_result()
688
690
  return self.rowcount
689
691
 
@@ -515,6 +515,8 @@ _schema_converters: Dict[
515
515
  'namedtuples': _no_schema,
516
516
  'dict': _no_schema,
517
517
  'dicts': _no_schema,
518
+ 'structsequence': _no_schema,
519
+ 'structsequences': _no_schema,
518
520
  'numpy': _description_to_numpy_schema,
519
521
  'pandas': _description_to_numpy_schema,
520
522
  'polars': _description_to_polars_schema,
@@ -578,4 +580,6 @@ def get_schema(
578
580
  for the given format type
579
581
 
580
582
  """
581
- return _schema_converters[format](desc) or {}
583
+ if format in _schema_converters:
584
+ return _schema_converters[format](desc) or {}
585
+ return {}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: singlestoredb
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: Interface to the SingleStoreDB database and workspace management APIs
5
5
  Home-page: https://github.com/singlestore-labs/singlestoredb-python
6
6
  Author: SingleStore
@@ -1,8 +1,8 @@
1
- _singlestoredb_accel.pyd,sha256=rrv8blK5R_XhFXscI7eVTgf08W-4OA9turT6M_5jp8o,59392
2
- singlestoredb/__init__.py,sha256=N6Vu7URdNgt7AMblqVfjo-AR-o0sI7NXdtqM0_JBLb8,1697
1
+ _singlestoredb_accel.pyd,sha256=u5N8fZtII5jhrswsZ2N0JRbwRJJgtYD_ci9SIMkvAAs,59392
2
+ singlestoredb/__init__.py,sha256=P-_L_CHfQOcteZO1mbDWyLUyDUfU5rFfOKIJfI1M0JU,1697
3
3
  singlestoredb/auth.py,sha256=RmYiH0Wlc2RXc4pTlRMysxtBI445ggCIwojWKC_eDLE,7844
4
4
  singlestoredb/config.py,sha256=9pVmVEZ23NfJ3pokdBDA0cX3bwUz6SbuT4AZWAcIPR4,12235
5
- singlestoredb/connection.py,sha256=e8ouONeUJvuIzyoFBwtUoiSTF_wGbBpOBRMZ5d5h9Vo,45825
5
+ singlestoredb/connection.py,sha256=F8lTA62nwnQ_r9-WYANnbIBqacdAuX0wXGaET9PNkXA,46410
6
6
  singlestoredb/converters.py,sha256=7_Of1f3Ow-JUoY1pHFlMPYxvt8llzdk-7X8qk5z2xJM,21631
7
7
  singlestoredb/exceptions.py,sha256=WCCJrNSsU-hD-621Jpd6bwmvGftQ7byXkk-XKXlaxpg,3354
8
8
  singlestoredb/pytest.py,sha256=TH364xRCN7_QaN0oRQDHixrEcDx_ZBgu3bmY0tvKrYU,9357
@@ -29,7 +29,7 @@ singlestoredb/fusion/handlers/stage.py,sha256=uPqawMvchnpyrPYLhB0joTremCURNYKOvY
29
29
  singlestoredb/fusion/handlers/utils.py,sha256=7xWb_1mJzxW0po9iHVY2ZVnRvHIQgOlKZQZ1zllJBjk,5271
30
30
  singlestoredb/fusion/handlers/workspace.py,sha256=lzTaa55QfKuwuSCGbrlk4B_hPQ6xcjZ8oZFDz-Vznxo,25815
31
31
  singlestoredb/http/__init__.py,sha256=4cEDvLloGc3LSpU-PnIwacyu0n5oIIIE6xk2SPyWD_w,939
32
- singlestoredb/http/connection.py,sha256=ASn90MSah73Lh8Wwt21I-OZAjjXCyPTy6Xo7hoaWu30,40048
32
+ singlestoredb/http/connection.py,sha256=zIkVfemoXPPlCDEvms698icd5nf8X_pK1YorDVgLDvs,40596
33
33
  singlestoredb/management/__init__.py,sha256=CjK47iU4WXJoq24EcXqBPCat4efAY20FR4qltWdxYf0,242
34
34
  singlestoredb/management/billing_usage.py,sha256=0UHFSPCrN0nyeGFFM-HXS3NP8pYmYo2BCCahDEPXvzg,3883
35
35
  singlestoredb/management/cluster.py,sha256=0GhpuSt_rcFz5f1hzcRHK911KWFewljlV4GFtckB8uM,14822
@@ -41,9 +41,9 @@ singlestoredb/management/workspace.py,sha256=4AbHlFy_n5obA7mmrRTFM3_wirou2NhYD9b
41
41
  singlestoredb/mysql/__init__.py,sha256=CbpwzNUJPAmKPpIobC0-ugBta_RgHCMq7X7N75QLReY,4669
42
42
  singlestoredb/mysql/_auth.py,sha256=YaqqyvAHmeraBv3BM207rNveUVPM-mPnW20ts_ynVWg,8341
43
43
  singlestoredb/mysql/charset.py,sha256=mnCdMpvdub1S2mm2PSk2j5JddgsWRjsVLtGx-y9TskE,10724
44
- singlestoredb/mysql/connection.py,sha256=QFI5W0Hai6S_3WNxVnls67WnZC2eZNdc2qiLLLkblO4,69779
44
+ singlestoredb/mysql/connection.py,sha256=bvf1JPYSAZFsZD9vxfj7giSTza2eYRvCgW-gK7E549U,72260
45
45
  singlestoredb/mysql/converters.py,sha256=vebFFm6IrC0WgY-5Eh-esaPizY5cq3vDOUlEKGaYM-U,7771
46
- singlestoredb/mysql/cursors.py,sha256=rWKsasmR3IchTDUUFiyfBbZaOg9mjrImsrZuUSRGTaM,27413
46
+ singlestoredb/mysql/cursors.py,sha256=pkrP-1t8IhBJRnYpdM7Rdm-332nOq1RYTDJ_yg_q5HI,27682
47
47
  singlestoredb/mysql/err.py,sha256=aDbmfq08gWVmfgIea735wSeiFdvYbB5wusgd3qTVq1s,2480
48
48
  singlestoredb/mysql/optionfile.py,sha256=bz0cZp8tQZvab1iU7OT0yldHyaMVbvAcUJ3TSNwcmyI,675
49
49
  singlestoredb/mysql/protocol.py,sha256=UzHcrv0Pgb1FNofuBTnSxpC9VDkgNbPEbBrRETstxAg,14888
@@ -109,11 +109,11 @@ singlestoredb/utils/convert_rows.py,sha256=gkZeZazeJvimCYEQ1FdAC-AmMDwmFGCuP6mi6
109
109
  singlestoredb/utils/debug.py,sha256=y7dnJeJGt3U_BWXz9pLt1qNQREpPtumYX_sk1DiqG6Y,362
110
110
  singlestoredb/utils/dtypes.py,sha256=_P2fTX2Fgv9Bcl-2L6KivhWgLzyu91sDamxVnmG92Mw,6103
111
111
  singlestoredb/utils/mogrify.py,sha256=gCcn99-vgsGVjTUV7RHJ6hH4vCNrsGB_Xo4z8kiSPDQ,4201
112
- singlestoredb/utils/results.py,sha256=sPjqp1x2rClFDMdKny4a0uQcYue2u1mvzLm3siwkDOI,15734
112
+ singlestoredb/utils/results.py,sha256=wR70LhCqlobniZf52r67zYLBOKjWHQm68NAskdRQND8,15862
113
113
  singlestoredb/utils/xdict.py,sha256=-wi1lSPTnY99fhVMBhPKJ8cCsQhNG4GMUfkEBDKYgCw,13321
114
- singlestoredb-1.2.0.dist-info/LICENSE,sha256=Bojenzui8aPNjlF3w4ojguDP7sTf8vFV_9Gc2UAG1sg,11542
115
- singlestoredb-1.2.0.dist-info/METADATA,sha256=GONdC2CBV7F35cjTubE3D20vM3eSA7VB1rO1SUbOD6A,5710
116
- singlestoredb-1.2.0.dist-info/WHEEL,sha256=UyMHzmWA0xVqVPKfTiLs2eN3OWWZUl-kQemNbpIqlKo,100
117
- singlestoredb-1.2.0.dist-info/entry_points.txt,sha256=bSLaTWB5zGjpVYPAaI46MkkDup0su-eb3uAhCNYuRV0,48
118
- singlestoredb-1.2.0.dist-info/top_level.txt,sha256=SDtemIXf-Kp-_F2f_S6x0db33cHGOILdAEsIQZe2LZc,35
119
- singlestoredb-1.2.0.dist-info/RECORD,,
114
+ singlestoredb-1.3.0.dist-info/LICENSE,sha256=Bojenzui8aPNjlF3w4ojguDP7sTf8vFV_9Gc2UAG1sg,11542
115
+ singlestoredb-1.3.0.dist-info/METADATA,sha256=qpvu-1Qn8cFUbBOPrD84XzIii6Y3lD-vAAS03s1wBmY,5710
116
+ singlestoredb-1.3.0.dist-info/WHEEL,sha256=UyMHzmWA0xVqVPKfTiLs2eN3OWWZUl-kQemNbpIqlKo,100
117
+ singlestoredb-1.3.0.dist-info/entry_points.txt,sha256=bSLaTWB5zGjpVYPAaI46MkkDup0su-eb3uAhCNYuRV0,48
118
+ singlestoredb-1.3.0.dist-info/top_level.txt,sha256=SDtemIXf-Kp-_F2f_S6x0db33cHGOILdAEsIQZe2LZc,35
119
+ singlestoredb-1.3.0.dist-info/RECORD,,