databricks-sql-connector 0.9.1__py3-none-any.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.
@@ -0,0 +1,240 @@
1
+ """Package private common utilities. Do not use directly.
2
+
3
+ Many docstrings in this file are based on PEP-249, which is in the public domain.
4
+ """
5
+
6
+ from __future__ import absolute_import
7
+ from __future__ import unicode_literals
8
+ from builtins import bytes
9
+ from builtins import int
10
+ from builtins import object
11
+ from builtins import str
12
+ from past.builtins import basestring
13
+ from databricks.sql import exc
14
+ import abc
15
+ import collections
16
+ import time
17
+ import datetime
18
+ from future.utils import with_metaclass
19
+ from itertools import islice
20
+
21
+
22
+ class DBAPICursor(with_metaclass(abc.ABCMeta, object)):
23
+ """Base class for some common DB-API logic"""
24
+
25
+ _STATE_NONE = 0
26
+ _STATE_RUNNING = 1
27
+ _STATE_FINISHED = 2
28
+
29
+ def __init__(self, poll_interval=1):
30
+ self._poll_interval = poll_interval
31
+ self._reset_state()
32
+ self.lastrowid = None
33
+
34
+ def _reset_state(self):
35
+ """Reset state about the previous query in preparation for running another query"""
36
+ # State to return as part of DB-API
37
+ self._rownumber = 0
38
+
39
+ # Internal helper state
40
+ self._state = self._STATE_NONE
41
+ self._data = collections.deque()
42
+ self._columns = None
43
+
44
+ def _fetch_while(self, fn):
45
+ while fn():
46
+ self._fetch_more()
47
+ if fn():
48
+ time.sleep(self._poll_interval)
49
+
50
+ @abc.abstractproperty
51
+ def description(self):
52
+ raise NotImplementedError # pragma: no cover
53
+
54
+ def close(self):
55
+ """By default, do nothing"""
56
+ pass
57
+
58
+ @abc.abstractmethod
59
+ def _fetch_more(self):
60
+ """Get more results, append it to ``self._data``, and update ``self._state``."""
61
+ raise NotImplementedError # pragma: no cover
62
+
63
+ @property
64
+ def rowcount(self):
65
+ """By default, return -1 to indicate that this is not supported."""
66
+ return -1
67
+
68
+ @abc.abstractmethod
69
+ def execute(self, operation, parameters=None):
70
+ """Prepare and execute a database operation (query or command).
71
+
72
+ Parameters may be provided as sequence or mapping and will be bound to variables in the
73
+ operation. Variables are specified in a database-specific notation (see the module's
74
+ ``paramstyle`` attribute for details).
75
+
76
+ Return values are not defined.
77
+ """
78
+ raise NotImplementedError # pragma: no cover
79
+
80
+ def executemany(self, operation, seq_of_parameters):
81
+ """Prepare a database operation (query or command) and then execute it against all parameter
82
+ sequences or mappings found in the sequence ``seq_of_parameters``.
83
+
84
+ Only the final result set is retained.
85
+
86
+ Return values are not defined.
87
+ """
88
+ for parameters in seq_of_parameters[:-1]:
89
+ self.execute(operation, parameters)
90
+ while self._state != self._STATE_FINISHED:
91
+ self._fetch_more()
92
+ if seq_of_parameters:
93
+ self.execute(operation, seq_of_parameters[-1])
94
+
95
+ def fetchone(self):
96
+ """Fetch the next row of a query result set, returning a single sequence, or ``None`` when
97
+ no more data is available.
98
+
99
+ An :py:class:`~databricks.sql.exc.Error` (or subclass) exception is raised if the previous call to
100
+ :py:meth:`execute` did not produce any result set or no call was issued yet.
101
+ """
102
+ if self._state == self._STATE_NONE:
103
+ raise exc.ProgrammingError("No query yet")
104
+
105
+ # Sleep until we're done or we have some data to return
106
+ self._fetch_while(lambda: not self._data and self._state != self._STATE_FINISHED)
107
+
108
+ if not self._data:
109
+ return None
110
+ else:
111
+ self._rownumber += 1
112
+ return self._data.popleft()
113
+
114
+ def fetchmany(self, size=None):
115
+ """Fetch the next set of rows of a query result, returning a sequence of sequences (e.g. a
116
+ list of tuples). An empty sequence is returned when no more rows are available.
117
+
118
+ The number of rows to fetch per call is specified by the parameter. If it is not given, the
119
+ cursor's arraysize determines the number of rows to be fetched. The method should try to
120
+ fetch as many rows as indicated by the size parameter. If this is not possible due to the
121
+ specified number of rows not being available, fewer rows may be returned.
122
+
123
+ An :py:class:`~databricks.exc.Error` (or subclass) exception is raised if the previous call to
124
+ :py:meth:`execute` did not produce any result set or no call was issued yet.
125
+ """
126
+ if size is None:
127
+ size = self.arraysize
128
+ return list(islice(iter(self.fetchone, None), size))
129
+
130
+ def fetchall(self):
131
+ """Fetch all (remaining) rows of a query result, returning them as a sequence of sequences
132
+ (e.g. a list of tuples).
133
+
134
+ An :py:class:`~databricks.exc.Error` (or subclass) exception is raised if the previous call to
135
+ :py:meth:`execute` did not produce any result set or no call was issued yet.
136
+ """
137
+ return list(iter(self.fetchone, None))
138
+
139
+ @property
140
+ def arraysize(self):
141
+ """This read/write attribute specifies the number of rows to fetch at a time with
142
+ :py:meth:`fetchmany`. It defaults to 1 meaning to fetch a single row at a time.
143
+ """
144
+ return self._arraysize
145
+
146
+ @arraysize.setter
147
+ def arraysize(self, value):
148
+ self._arraysize = value
149
+
150
+ def setinputsizes(self, sizes):
151
+ """Does nothing by default"""
152
+ pass
153
+
154
+ def setoutputsize(self, size, column=None):
155
+ """Does nothing by default"""
156
+ pass
157
+
158
+ #
159
+ # Optional DB API Extensions
160
+ #
161
+
162
+ @property
163
+ def rownumber(self):
164
+ """This read-only attribute should provide the current 0-based index of the cursor in the
165
+ result set.
166
+
167
+ The index can be seen as index of the cursor in a sequence (the result set). The next fetch
168
+ operation will fetch the row indexed by ``rownumber`` in that sequence.
169
+ """
170
+ return self._rownumber
171
+
172
+ def __next__(self):
173
+ """Return the next row from the currently executing SQL statement using the same semantics
174
+ as :py:meth:`fetchone`. A ``StopIteration`` exception is raised when the result set is
175
+ exhausted.
176
+ """
177
+ one = self.fetchone()
178
+ if one is None:
179
+ raise StopIteration
180
+ else:
181
+ return one
182
+
183
+ next = __next__
184
+
185
+ def __iter__(self):
186
+ """Return self to make cursors compatible to the iteration protocol."""
187
+ return self
188
+
189
+ class ParamEscaper(object):
190
+ _DATE_FORMAT = "%Y-%m-%d"
191
+ _TIME_FORMAT = "%H:%M:%S.%f"
192
+ _DATETIME_FORMAT = "{} {}".format(_DATE_FORMAT, _TIME_FORMAT)
193
+
194
+ def escape_args(self, parameters):
195
+ if isinstance(parameters, dict):
196
+ return {k: self.escape_item(v) for k, v in parameters.items()}
197
+ elif isinstance(parameters, (list, tuple)):
198
+ return tuple(self.escape_item(x) for x in parameters)
199
+ else:
200
+ raise exc.ProgrammingError("Unsupported param format: {}".format(parameters))
201
+
202
+ def escape_number(self, item):
203
+ return item
204
+
205
+ def escape_string(self, item):
206
+ # Need to decode UTF-8 because of old sqlalchemy.
207
+ # Newer SQLAlchemy checks dialect.supports_unicode_binds before encoding Unicode strings
208
+ # as byte strings. The old version always encodes Unicode as byte strings, which breaks
209
+ # string formatting here.
210
+ if isinstance(item, bytes):
211
+ item = item.decode('utf-8')
212
+ # This is good enough when backslashes are literal, newlines are just followed, and the way
213
+ # to escape a single quote is to put two single quotes.
214
+ # (i.e. only special character is single quote)
215
+ return "'{}'".format(item.replace("'", "''"))
216
+
217
+ def escape_sequence(self, item):
218
+ l = map(str, map(self.escape_item, item))
219
+ return '(' + ','.join(l) + ')'
220
+
221
+ def escape_datetime(self, item, format, cutoff=0):
222
+ dt_str = item.strftime(format)
223
+ formatted = dt_str[:-cutoff] if cutoff and format.endswith(".%f") else dt_str
224
+ return "'{}'".format(formatted)
225
+
226
+ def escape_item(self, item):
227
+ if item is None:
228
+ return 'NULL'
229
+ elif isinstance(item, (int, float)):
230
+ return self.escape_number(item)
231
+ elif isinstance(item, basestring):
232
+ return self.escape_string(item)
233
+ elif isinstance(item, collections.Iterable):
234
+ return self.escape_sequence(item)
235
+ elif isinstance(item, datetime.datetime):
236
+ return self.escape_datetime(item, self._DATETIME_FORMAT)
237
+ elif isinstance(item, datetime.date):
238
+ return self.escape_datetime(item, self._DATE_FORMAT)
239
+ else:
240
+ raise exc.ProgrammingError("Unsupported object {}".format(item))
@@ -0,0 +1,36 @@
1
+ import datetime
2
+
3
+ #
4
+ # PEP 249 module globals
5
+ #
6
+ apilevel = '2.0'
7
+ threadsafety = 1 # Threads may share the module, but not connections.
8
+ paramstyle = 'pyformat' # Python extended format codes, e.g. ...WHERE name=%(name)s
9
+
10
+ #
11
+ # Type Objects and Constructors
12
+ #
13
+
14
+ class DBAPITypeObject(object):
15
+ def __init__(self, *values):
16
+ self.values = values
17
+
18
+ def __eq__(self, other):
19
+ return other in self.values
20
+
21
+ STRING = DBAPITypeObject('string')
22
+ BINARY = DBAPITypeObject('binary')
23
+ NUMBER = DBAPITypeObject('boolean', 'tinyint', 'smallint', 'int', 'bigint',
24
+ 'float', 'double', 'decimal')
25
+ DATETIME = DBAPITypeObject('timestamp')
26
+ DATE = DBAPITypeObject('date')
27
+ ROWID = DBAPITypeObject()
28
+
29
+ Date = datetime.date
30
+ Timestamp = datetime.datetime
31
+
32
+ def DateFromTicks(ticks):
33
+ return Date(*time.localtime(ticks)[:3])
34
+
35
+ def TimestampFromTicks(ticks):
36
+ return Timestamp(*time.localtime(ticks)[:6])
databricks/sql/exc.py ADDED
@@ -0,0 +1,72 @@
1
+ """
2
+ Package private common utilities. Do not use directly.
3
+ """
4
+ from __future__ import absolute_import
5
+ from __future__ import unicode_literals
6
+
7
+ __all__ = [
8
+ 'Error', 'Warning', 'InterfaceError', 'DatabaseError', 'InternalError', 'OperationalError',
9
+ 'ProgrammingError', 'DataError', 'NotSupportedError',
10
+ ]
11
+
12
+
13
+ class Error(Exception):
14
+ """Exception that is the base class of all other error exceptions.
15
+
16
+ You can use this to catch all errors with one single except statement.
17
+ """
18
+ pass
19
+
20
+
21
+ class Warning(Exception):
22
+ """Exception raised for important warnings like data truncations while inserting, etc."""
23
+ pass
24
+
25
+
26
+ class InterfaceError(Error):
27
+ """Exception raised for errors that are related to the database interface rather than the
28
+ database itself.
29
+ """
30
+ pass
31
+
32
+
33
+ class DatabaseError(Error):
34
+ """Exception raised for errors that are related to the database."""
35
+ pass
36
+
37
+
38
+ class InternalError(DatabaseError):
39
+ """Exception raised when the database encounters an internal error, e.g. the cursor is not valid
40
+ anymore, the transaction is out of sync, etc."""
41
+ pass
42
+
43
+
44
+ class OperationalError(DatabaseError):
45
+ """Exception raised for errors that are related to the database's operation and not necessarily
46
+ under the control of the programmer, e.g. an unexpected disconnect occurs, the data source name
47
+ is not found, a transaction could not be processed, a memory allocation error occurred during
48
+ processing, etc.
49
+ """
50
+ pass
51
+
52
+
53
+ class ProgrammingError(DatabaseError):
54
+ """Exception raised for programming errors, e.g. table not found or already exists, syntax error
55
+ in the SQL statement, wrong number of parameters specified, etc.
56
+ """
57
+ pass
58
+
59
+
60
+ class DataError(DatabaseError):
61
+ """Exception raised for errors that are due to problems with the processed data like division by
62
+ zero, numeric value out of range, etc.
63
+ """
64
+ pass
65
+
66
+
67
+ class NotSupportedError(DatabaseError):
68
+ """Exception raised in case a method or database API was used which is not supported by the
69
+ database, e.g. requesting a ``.rollback()`` on a connection that does not support transaction or
70
+ has transactions turned off.
71
+ """
72
+ pass
@@ -0,0 +1,13 @@
1
+ Copyright 2021-present Databricks Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,66 @@
1
+ Metadata-Version: 2.1
2
+ Name: databricks-sql-connector
3
+ Version: 0.9.1
4
+ Summary: Databricks SQL Connector for Python
5
+ Home-page: https://databricks.com
6
+ Author: Databricks
7
+ Author-email: feedback@databricks.com
8
+ License: http://www.apache.org/licenses/LICENSE-2.0
9
+ Platform: UNKNOWN
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: Apache Software License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Topic :: Database :: Front-Ends
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ License-File: NOTICE
17
+ Requires-Dist: future
18
+ Requires-Dist: python-dateutil
19
+ Requires-Dist: thrift (>=0.10.0)
20
+
21
+ # Databricks SQL Connector for Python
22
+
23
+ **Status: Public Preview**
24
+
25
+ This library is currently shared as [Public Preview](https://docs.databricks.com/release-notes/release-types.html). Documentation can be found here: [Databricks SQL Connector for Python
26
+ ](https://docs.databricks.com/dev-tools/python-sql-connector.html).
27
+
28
+ ## About
29
+
30
+ The Databricks SQL Connector is a Python library that allows you to use Python code to run
31
+ SQL commands on Databricks clusters and Databricks SQL endpoints.
32
+ This library follows [PEP 249 -- Python Database API Specification v2.0](https://www.python.org/dev/peps/pep-0249/).
33
+
34
+ ## Quickstart
35
+
36
+ Install the library with `pip install databricks-sql-connector`
37
+
38
+ Example usage:
39
+
40
+ ```
41
+ from databricks import sql
42
+
43
+ connection = sql.connect(
44
+ server_hostname='<server-hostname>',
45
+ http_path='<http-path>',
46
+ access_token='<personal-access-token>')
47
+
48
+ cursor = connection.cursor()
49
+
50
+ cursor.execute('SELECT * FROM RANGE(10)')
51
+ result = cursor.fetchall()
52
+ for row in result:
53
+ print(row)
54
+
55
+ connection.close()
56
+ ```
57
+
58
+ Where:
59
+ - `<server-hostname>` is the Databricks instance host name.
60
+ - `<http-path>` is the HTTP Path either to a Databricks SQL endpoint (e.g. /sql/1.0/endpoints/1234567890abcdef),
61
+ or to a Databricks Runtime interactive cluster (e.g. /sql/protocolv1/o/1234567890123456/1234-123456-slid123)
62
+ - `<personal-access-token>` is a HTTP Bearer access token, e.g. a Databricks Personal Access Token.
63
+
64
+ For more information, see [Databricks documentation](https://docs.databricks.com/dev-tools/python-sql-connector.html).
65
+
66
+
@@ -0,0 +1,23 @@
1
+ databricks-sql-connector
2
+ Copyright 2021-present Databricks, Inc.
3
+ All Rights Reserved
4
+
5
+ This product is subject to the included LICENSE file and
6
+ includes source code derived from software mentioned below.
7
+
8
+ ---
9
+ https://github.com/dropbox/PyHive
10
+ Copyright (c) 2014 Dropbox, Inc.
11
+
12
+ Licensed under the Apache License, Version 2.0 (the "License");
13
+ you may not use this file except in compliance with the License.
14
+ You may obtain a copy of the License at
15
+
16
+ http://www.apache.org/licenses/LICENSE-2.0
17
+
18
+ Unless required by applicable law or agreed to in writing, software
19
+ distributed under the License is distributed on an "AS IS" BASIS,
20
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
+ See the License for the specific language governing permissions and
22
+ limitations under the License.LICENSE file containing the Databricks license
23
+ ---
@@ -0,0 +1,16 @@
1
+ databricks/__init__.py,sha256=jv2YF__bseklT3OWEzlqJ5qE24c4aWd5F4r0TTjOrWQ,65
2
+ databricks/sql/__init__.py,sha256=RFKD6i1HXjCPPeYXXxjCIO8IrP_A4a2D3WMML2beRM8,1037
3
+ databricks/sql/client.py,sha256=BFpeTRB-m8UE-vFwm-xuGlDP49FQ1RMsooWxH7CJz70,17719
4
+ databricks/sql/common.py,sha256=u5NY2miRwr1fkYNM7CeXM7wo8VB_8x0silDm96OCIXo,8803
5
+ databricks/sql/dbapi.py,sha256=bGKQnKo0TM2Eo7EoU3V-ihn2BtN5MGkcjFq5uj6FMyY,919
6
+ databricks/sql/exc.py,sha256=syjd3bTnNW9gSIX9XA0xrc23mpB97XKXHE7SV2witIY,2196
7
+ databricks/sql/TCLIService/TCLIService.py,sha256=dSW76LC_0GILt2lUjjqpOtq4jTLi7C4qg-Dc9fVo-vY,131364
8
+ databricks/sql/TCLIService/__init__.py,sha256=XERxa3ZbrWjXGs8DuVmNGw8jth4LsnQPJnAGCG3PacU,49
9
+ databricks/sql/TCLIService/constants.py,sha256=iTFnQWnw4GDxZycJRLDGKGCvfjT3CiuCfhnU4Bynvws,1087
10
+ databricks/sql/TCLIService/ttypes.py,sha256=iMrIfTL_wPCrcoNEwguUvISiz3ZWDC4nDZ1NLWoZzvU,263044
11
+ databricks_sql_connector-0.9.1.dist-info/LICENSE,sha256=vu00SutTcQDyMHQv91CyBo28hp7PuGqZvVmdyclqEbE,562
12
+ databricks_sql_connector-0.9.1.dist-info/METADATA,sha256=B2NUGRkCrX12v-4s7cqDQWgYjWAsO8YdRm3o5n_DR_U,2182
13
+ databricks_sql_connector-0.9.1.dist-info/NOTICE,sha256=i-8Gh88vPGOFP7FF7yVo4bOXJeaMbCZZ6qZJ7EXXhqI,851
14
+ databricks_sql_connector-0.9.1.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92
15
+ databricks_sql_connector-0.9.1.dist-info/top_level.txt,sha256=7kRdatoSgU0EUurRQJ_3F1Nv4EOSHWAr6ng25tJOJKU,11
16
+ databricks_sql_connector-0.9.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.37.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ databricks