databricks-sql-connector 3.0.0__tar.gz → 3.0.1__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.
Files changed (56) hide show
  1. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/CHANGELOG.md +7 -0
  2. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/PKG-INFO +1 -1
  3. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/pyproject.toml +1 -1
  4. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/__init__.py +1 -1
  5. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/client.py +13 -9
  6. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/_parse.py +4 -1
  7. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/base.py +1 -1
  8. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test_local/e2e/test_basic.py +43 -11
  9. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/LICENSE +0 -0
  10. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/README.md +0 -0
  11. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/__init__.py +0 -0
  12. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/auth/__init__.py +0 -0
  13. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/auth/auth.py +0 -0
  14. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/auth/authenticators.py +0 -0
  15. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/auth/endpoint.py +0 -0
  16. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/auth/oauth.py +0 -0
  17. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/auth/oauth_http_handler.py +0 -0
  18. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/auth/retry.py +0 -0
  19. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/auth/thrift_http_client.py +0 -0
  20. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/cloudfetch/download_manager.py +0 -0
  21. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/cloudfetch/downloader.py +0 -0
  22. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/exc.py +0 -0
  23. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/experimental/__init__.py +0 -0
  24. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/experimental/oauth_persistence.py +0 -0
  25. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/parameters/__init__.py +0 -0
  26. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/parameters/native.py +0 -0
  27. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/parameters/py.typed +0 -0
  28. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/thrift_api/TCLIService/TCLIService-remote +0 -0
  29. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/thrift_api/TCLIService/TCLIService.py +0 -0
  30. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/thrift_api/TCLIService/__init__.py +0 -0
  31. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/thrift_api/TCLIService/constants.py +0 -0
  32. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/thrift_api/TCLIService/ttypes.py +0 -0
  33. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/thrift_api/__init__.py +0 -0
  34. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/thrift_backend.py +0 -0
  35. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/types.py +0 -0
  36. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sql/utils.py +0 -0
  37. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/README.sqlalchemy.md +0 -0
  38. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/README.tests.md +0 -0
  39. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/__init__.py +0 -0
  40. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/_ddl.py +0 -0
  41. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/_types.py +0 -0
  42. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/pytest.ini +0 -0
  43. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/requirements.py +0 -0
  44. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/setup.cfg +0 -0
  45. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test/_extra.py +0 -0
  46. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test/_future.py +0 -0
  47. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test/_regression.py +0 -0
  48. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test/_unsupported.py +0 -0
  49. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test/conftest.py +0 -0
  50. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test/overrides/_componentreflectiontest.py +0 -0
  51. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test/overrides/_ctetest.py +0 -0
  52. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test/test_suite.py +0 -0
  53. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test_local/__init__.py +0 -0
  54. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test_local/e2e/MOCK_DATA.xlsx +0 -0
  55. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test_local/test_parsing.py +0 -0
  56. {databricks_sql_connector-3.0.0 → databricks_sql_connector-3.0.1}/src/databricks/sqlalchemy/test_local/test_types.py +0 -0
@@ -1,5 +1,12 @@
1
1
  # Release History
2
2
 
3
+ ## 3.0.1 (2023-12-01)
4
+
5
+ - Other: updated docstring comment about default parameterization approach (#287)
6
+ - Other: added tests for reading complex types and revised docstrings and type hints (#293)
7
+ - Fix: SQLAlchemy dialect raised DeprecationWarning due to `dbapi` classmethod (#294)
8
+ - Fix: SQLAlchemy dialect could not reflect TIMESTAMP_NTZ columns (#296)
9
+
3
10
  ## 3.0.0 (2023-11-17)
4
11
 
5
12
  - Remove support for Python 3.7
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: databricks-sql-connector
3
- Version: 3.0.0
3
+ Version: 3.0.1
4
4
  Summary: Databricks SQL Connector for Python
5
5
  License: Apache-2.0
6
6
  Author: Databricks
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "databricks-sql-connector"
3
- version = "3.0.0"
3
+ version = "3.0.1"
4
4
  description = "Databricks SQL Connector for Python"
5
5
  authors = ["Databricks <databricks-sql-connector-maintainers@databricks.com>"]
6
6
  license = "Apache-2.0"
@@ -29,7 +29,7 @@ DATETIME = DBAPITypeObject("timestamp")
29
29
  DATE = DBAPITypeObject("date")
30
30
  ROWID = DBAPITypeObject()
31
31
 
32
- __version__ = "3.0.0"
32
+ __version__ = "3.0.1"
33
33
  USER_AGENT_NAME = "PyDatabricksSqlConnector"
34
34
 
35
35
  # These two functions are pyhive legacy
@@ -61,6 +61,7 @@ class Connection:
61
61
  session_configuration: Dict[str, Any] = None,
62
62
  catalog: Optional[str] = None,
63
63
  schema: Optional[str] = None,
64
+ _use_arrow_native_complex_types: Optional[bool] = True,
64
65
  **kwargs,
65
66
  ) -> None:
66
67
  """
@@ -152,8 +153,13 @@ class Connection:
152
153
  experimental_oauth_persistence=DevOnlyFilePersistence("~/dev-oauth.json")
153
154
  )
154
155
  ```
155
-
156
-
156
+ :param _use_arrow_native_complex_types: `bool`, optional
157
+ Controls whether a complex type field value is returned as a string or as a native Arrow type. Defaults to True.
158
+ When True:
159
+ MAP is returned as List[Tuple[str, Any]]
160
+ STRUCT is returned as Dict[str, Any]
161
+ ARRAY is returned as numpy.ndarray
162
+ When False, complex types are returned as a strings. These are generally deserializable as JSON.
157
163
  """
158
164
 
159
165
  # Internal arguments in **kwargs:
@@ -184,9 +190,6 @@ class Connection:
184
190
  # _disable_pandas
185
191
  # In case the deserialisation through pandas causes any issues, it can be disabled with
186
192
  # this flag.
187
- # _use_arrow_native_complex_types
188
- # DBR will return native Arrow types for structs, arrays and maps instead of Arrow strings
189
- # (True by default)
190
193
  # _use_arrow_native_decimals
191
194
  # Databricks runtime will return native Arrow types for decimals instead of Arrow strings
192
195
  # (True by default)
@@ -225,6 +228,7 @@ class Connection:
225
228
  http_path,
226
229
  (http_headers or []) + base_headers,
227
230
  auth_provider,
231
+ _use_arrow_native_complex_types=_use_arrow_native_complex_types,
228
232
  **kwargs,
229
233
  )
230
234
 
@@ -709,18 +713,18 @@ class Cursor:
709
713
  Execute a query and wait for execution to complete.
710
714
 
711
715
  The parameterisation behaviour of this method depends on which parameter approach is used:
712
- - With INLINE mode (default), parameters are rendered inline with the query text
713
- - With NATIVE mode, parameters are sent to the server separately for binding
716
+ - With INLINE mode, parameters are rendered inline with the query text
717
+ - With NATIVE mode (default), parameters are sent to the server separately for binding
714
718
 
715
719
  This behaviour is controlled by the `use_inline_params` argument passed when building a connection.
716
720
 
717
721
  The paramstyle for these approaches is different:
718
722
 
719
- If the connection was instantiated with use_inline_params=False, then parameters
723
+ If the connection was instantiated with use_inline_params=False (default), then parameters
720
724
  should be given in PEP-249 `named` paramstyle like :param_name. Parameters passed by positionally
721
725
  are indicated using a `?` in the query text.
722
726
 
723
- If the connection was instantiated with use_inline_params=True (default), then parameters
727
+ If the connection was instantiated with use_inline_params=True, then parameters
724
728
  should be given in PEP-249 `pyformat` paramstyle like %(param_name)s. Parameters passed by positionally
725
729
  are indicated using a `%s` marker in the query. Note: this approach is not recommended as it can break
726
730
  your SQL query syntax and will be removed in a future release.
@@ -5,6 +5,8 @@ import sqlalchemy
5
5
  from sqlalchemy.engine import CursorResult
6
6
  from sqlalchemy.engine.interfaces import ReflectedColumn
7
7
 
8
+ from databricks.sqlalchemy import _types as type_overrides
9
+
8
10
  """
9
11
  This module contains helper functions that can parse the contents
10
12
  of metadata and exceptions received from DBR. These are mostly just
@@ -293,7 +295,8 @@ GET_COLUMNS_TYPE_MAP = {
293
295
  "struct": sqlalchemy.types.String,
294
296
  "uniontype": sqlalchemy.types.String,
295
297
  "decimal": sqlalchemy.types.Numeric,
296
- "timestamp": sqlalchemy.types.DateTime,
298
+ "timestamp": type_overrides.TIMESTAMP,
299
+ "timestamp_ntz": type_overrides.TIMESTAMP_NTZ,
297
300
  "date": sqlalchemy.types.Date,
298
301
  }
299
302
 
@@ -82,7 +82,7 @@ class DatabricksDialect(default.DefaultDialect):
82
82
  EMPTY_FK = EMPTY_INDEX = []
83
83
 
84
84
  @classmethod
85
- def dbapi(cls):
85
+ def import_dbapi(cls):
86
86
  return sql
87
87
 
88
88
  def _force_paramstyle_to_native_mode(self):
@@ -1,21 +1,24 @@
1
- import os, datetime, decimal
2
- import pytest
1
+ import datetime
2
+ import decimal
3
+ import os
4
+ from typing import Tuple, Union
3
5
  from unittest import skipIf
6
+
7
+ import pytest
4
8
  from sqlalchemy import (
5
- create_engine,
6
- select,
7
- insert,
8
9
  Column,
9
10
  MetaData,
10
11
  Table,
11
12
  Text,
13
+ create_engine,
14
+ insert,
15
+ select,
12
16
  text,
13
17
  )
14
- from sqlalchemy.orm import Session, DeclarativeBase, Mapped, mapped_column
15
- from sqlalchemy.types import SMALLINT, Integer, BOOLEAN, String, DECIMAL, Date
16
18
  from sqlalchemy.engine import Engine
17
-
18
- from typing import Tuple, Union
19
+ from sqlalchemy.engine.reflection import Inspector
20
+ from sqlalchemy.orm import DeclarativeBase, Mapped, Session, mapped_column
21
+ from sqlalchemy.types import BOOLEAN, DECIMAL, Date, DateTime, Integer, String
19
22
 
20
23
  try:
21
24
  from sqlalchemy.orm import declarative_base
@@ -344,8 +347,6 @@ def test_dialect_type_mappings(db_engine, metadata_obj: MetaData):
344
347
  def test_inspector_smoke_test(samples_engine: Engine):
345
348
  """It does not appear that 3L namespace is supported here"""
346
349
 
347
- from sqlalchemy.engine.reflection import Inspector
348
-
349
350
  schema, table = "nyctaxi", "trips"
350
351
 
351
352
  try:
@@ -431,3 +432,34 @@ def test_user_agent_adjustment(db_engine):
431
432
  c2.close()
432
433
 
433
434
  assert same_ua, f"User agents didn't match \n {ua1} \n {ua2}"
435
+
436
+
437
+ @pytest.fixture
438
+ def sample_table(metadata_obj: MetaData, db_engine: Engine):
439
+ """This fixture creates a sample table and cleans it up after the test is complete."""
440
+ from databricks.sqlalchemy._parse import GET_COLUMNS_TYPE_MAP
441
+
442
+ table_name = "PySQLTest_{}".format(datetime.datetime.utcnow().strftime("%s"))
443
+
444
+ args = [
445
+ Column(colname, coltype) for colname, coltype in GET_COLUMNS_TYPE_MAP.items()
446
+ ]
447
+
448
+ SampleTable = Table(table_name, metadata_obj, *args)
449
+
450
+ metadata_obj.create_all(db_engine)
451
+
452
+ yield table_name
453
+
454
+ metadata_obj.drop_all(db_engine)
455
+
456
+
457
+ def test_get_columns(db_engine, sample_table: str):
458
+ """Created after PECO-1297 and Github Issue #295 to verify that get_columsn behaves like it should for all known SQLAlchemy types"""
459
+
460
+ inspector = Inspector.from_engine(db_engine)
461
+
462
+ # this raises an exception if `parse_column_info_from_tgetcolumnsresponse` fails a lookup
463
+ columns = inspector.get_columns(sample_table)
464
+
465
+ assert True