databricks-sql-connector 4.0.3__tar.gz → 4.0.5__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 (35) hide show
  1. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/CHANGELOG.md +12 -0
  2. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/PKG-INFO +3 -2
  3. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/pyproject.toml +1 -1
  4. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/__init__.py +1 -1
  5. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/client.py +23 -1
  6. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/parameters/__init__.py +2 -0
  7. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/parameters/native.py +125 -11
  8. databricks_sql_connector-4.0.5/src/databricks/sql/thrift_api/TCLIService/ttypes.py +50630 -0
  9. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/thrift_backend.py +17 -0
  10. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/utils.py +38 -17
  11. databricks_sql_connector-4.0.3/src/databricks/sql/thrift_api/TCLIService/ttypes.py +0 -111775
  12. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/LICENSE +0 -0
  13. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/README.md +0 -0
  14. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/__init__.py +0 -0
  15. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/auth/__init__.py +0 -0
  16. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/auth/auth.py +0 -0
  17. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/auth/authenticators.py +0 -0
  18. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/auth/endpoint.py +0 -0
  19. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/auth/oauth.py +0 -0
  20. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/auth/oauth_http_handler.py +0 -0
  21. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/auth/retry.py +0 -0
  22. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/auth/thrift_http_client.py +0 -0
  23. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/cloudfetch/download_manager.py +0 -0
  24. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/cloudfetch/downloader.py +0 -0
  25. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/exc.py +0 -0
  26. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/experimental/__init__.py +0 -0
  27. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/experimental/oauth_persistence.py +0 -0
  28. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/parameters/py.typed +0 -0
  29. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/py.typed +0 -0
  30. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/thrift_api/TCLIService/TCLIService-remote +0 -0
  31. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/thrift_api/TCLIService/TCLIService.py +0 -0
  32. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/thrift_api/TCLIService/__init__.py +0 -0
  33. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/thrift_api/TCLIService/constants.py +0 -0
  34. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/thrift_api/__init__.py +0 -0
  35. {databricks_sql_connector-4.0.3 → databricks_sql_connector-4.0.5}/src/databricks/sql/types.py +0 -0
@@ -1,5 +1,17 @@
1
1
  # Release History
2
2
 
3
+ # 4.0.5 (2025-06-24)
4
+ - Fix: Reverted change in cursor close handling which led to errors impacting users (databricks/databricks-sql-python#613 by @madhav-db)
5
+
6
+ # 4.0.4 (2025-06-16)
7
+
8
+ - Update thrift client library after cleaning up unused fields and structs (databricks/databricks-sql-python#553 by @vikrantpuppala)
9
+ - Refactor decimal conversion in PyArrow tables to use direct casting (databricks/databricks-sql-python#544 by @jayantsing-db)
10
+ - Fix: `fetchall_arrow` to always return results in `arrow` format (databricks/databricks-sql-python#551 by @shivam2680)
11
+ - Enhance cursor close handling and context manager exception management to prevent server side resource leaks (databricks/databricks-sql-python#554 by @madhav-db)
12
+ - Added additional logging to enhance debugging (databricks/databricks-sql-python#556 by @saishreeeee)
13
+ - Feature: Added support for complex data types such as Arrays and Map [Private Preview] (databricks/databricks-sql-python#559 by @jprakash-db)
14
+
3
15
  # 4.0.3 (2025-04-22)
4
16
 
5
17
  - Fix: Removed `packaging` dependency in favour of default libraries, for `urllib3` version checks (databricks/databricks-sql-python#547 by @jprakash-db)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: databricks-sql-connector
3
- Version: 4.0.3
3
+ Version: 4.0.5
4
4
  Summary: Databricks SQL Connector for Python
5
5
  License: Apache-2.0
6
6
  Author: Databricks
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.9
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
16
17
  Provides-Extra: pyarrow
17
18
  Requires-Dist: lz4 (>=4.0.2,<5.0.0)
18
19
  Requires-Dist: oauthlib (>=3.1.0,<4.0.0)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "databricks-sql-connector"
3
- version = "4.0.3"
3
+ version = "4.0.5"
4
4
  description = "Databricks SQL Connector for Python"
5
5
  authors = ["Databricks <databricks-sql-connector-maintainers@databricks.com>"]
6
6
  license = "Apache-2.0"
@@ -68,7 +68,7 @@ DATETIME = DBAPITypeObject("timestamp")
68
68
  DATE = DBAPITypeObject("date")
69
69
  ROWID = DBAPITypeObject()
70
70
 
71
- __version__ = "4.0.3"
71
+ __version__ = "4.0.5"
72
72
  USER_AGENT_NAME = "PyDatabricksSqlConnector"
73
73
 
74
74
  # These two functions are pyhive legacy
@@ -214,6 +214,12 @@ class Connection:
214
214
  # use_cloud_fetch
215
215
  # Enable use of cloud fetch to extract large query results in parallel via cloud storage
216
216
 
217
+ logger.debug(
218
+ "Connection.__init__(server_hostname=%s, http_path=%s)",
219
+ server_hostname,
220
+ http_path,
221
+ )
222
+
217
223
  if access_token:
218
224
  access_token_kv = {"access_token": access_token}
219
225
  kwargs = {**kwargs, **access_token_kv}
@@ -787,6 +793,9 @@ class Cursor:
787
793
 
788
794
  :returns self
789
795
  """
796
+ logger.debug(
797
+ "Cursor.execute(operation=%s, parameters=%s)", operation, parameters
798
+ )
790
799
 
791
800
  param_approach = self._determine_parameter_approach(parameters)
792
801
  if param_approach == ParameterApproach.NONE:
@@ -1415,9 +1424,22 @@ class ResultSet:
1415
1424
  while not self.has_been_closed_server_side and self.has_more_rows:
1416
1425
  self._fill_results_buffer()
1417
1426
  partial_results = self.results.remaining_rows()
1418
- results = pyarrow.concat_tables([results, partial_results])
1427
+ if isinstance(results, ColumnTable) and isinstance(
1428
+ partial_results, ColumnTable
1429
+ ):
1430
+ results = self.merge_columnar(results, partial_results)
1431
+ else:
1432
+ results = pyarrow.concat_tables([results, partial_results])
1419
1433
  self._next_row_index += partial_results.num_rows
1420
1434
 
1435
+ # If PyArrow is installed and we have a ColumnTable result, convert it to PyArrow Table
1436
+ # Valid only for metadata commands result set
1437
+ if isinstance(results, ColumnTable) and pyarrow:
1438
+ data = {
1439
+ name: col
1440
+ for name, col in zip(results.column_names, results.column_table)
1441
+ }
1442
+ return pyarrow.Table.from_pydict(data)
1421
1443
  return results
1422
1444
 
1423
1445
  def fetchall_columnar(self):
@@ -12,4 +12,6 @@ from databricks.sql.parameters.native import (
12
12
  TimestampNTZParameter,
13
13
  TinyIntParameter,
14
14
  DecimalParameter,
15
+ MapParameter,
16
+ ArrayParameter,
15
17
  )
@@ -1,12 +1,13 @@
1
1
  import datetime
2
2
  import decimal
3
3
  from enum import Enum, auto
4
- from typing import Optional, Sequence
4
+ from typing import Optional, Sequence, Any
5
5
 
6
6
  from databricks.sql.exc import NotSupportedError
7
7
  from databricks.sql.thrift_api.TCLIService.ttypes import (
8
8
  TSparkParameter,
9
9
  TSparkParameterValue,
10
+ TSparkParameterValueArg,
10
11
  )
11
12
 
12
13
  import datetime
@@ -54,7 +55,17 @@ class DatabricksSupportedType(Enum):
54
55
 
55
56
 
56
57
  TAllowedParameterValue = Union[
57
- str, int, float, datetime.datetime, datetime.date, bool, decimal.Decimal, None
58
+ str,
59
+ int,
60
+ float,
61
+ datetime.datetime,
62
+ datetime.date,
63
+ bool,
64
+ decimal.Decimal,
65
+ None,
66
+ list,
67
+ dict,
68
+ tuple,
58
69
  ]
59
70
 
60
71
 
@@ -82,6 +93,7 @@ class DbsqlParameterBase:
82
93
 
83
94
  CAST_EXPR: str
84
95
  name: Optional[str]
96
+ value: Any
85
97
 
86
98
  def as_tspark_param(self, named: bool) -> TSparkParameter:
87
99
  """Returns a TSparkParameter object that can be passed to the DBR thrift server."""
@@ -98,6 +110,10 @@ class DbsqlParameterBase:
98
110
  def _tspark_param_value(self):
99
111
  return TSparkParameterValue(stringValue=str(self.value))
100
112
 
113
+ def _tspark_value_arg(self):
114
+ """Returns a TSparkParameterValueArg object that can be passed to the DBR thrift server."""
115
+ return TSparkParameterValueArg(value=str(self.value), type=self._cast_expr())
116
+
101
117
  def _cast_expr(self):
102
118
  return self.CAST_EXPR
103
119
 
@@ -428,6 +444,99 @@ class TinyIntParameter(DbsqlParameterBase):
428
444
  CAST_EXPR = DatabricksSupportedType.TINYINT.name
429
445
 
430
446
 
447
+ class ArrayParameter(DbsqlParameterBase):
448
+ """Wrap a Python `Sequence` that will be bound to a Databricks SQL ARRAY type."""
449
+
450
+ def __init__(self, value: Sequence[Any], name: Optional[str] = None):
451
+ """
452
+ :value:
453
+ The value to bind for this parameter. This will be casted to a ARRAY.
454
+ :name:
455
+ If None, your query must contain a `?` marker. Like:
456
+
457
+ ```sql
458
+ SELECT * FROM table WHERE field = ?
459
+ ```
460
+ If not None, your query should contain a named parameter marker. Like:
461
+ ```sql
462
+ SELECT * FROM table WHERE field = :my_param
463
+ ```
464
+
465
+ The `name` argument to this function would be `my_param`.
466
+ """
467
+ self.name = name
468
+ self.value = [dbsql_parameter_from_primitive(val) for val in value]
469
+
470
+ def as_tspark_param(self, named: bool = False) -> TSparkParameter:
471
+ """Returns a TSparkParameter object that can be passed to the DBR thrift server."""
472
+
473
+ tsp = TSparkParameter(type=self._cast_expr())
474
+ tsp.arguments = [val._tspark_value_arg() for val in self.value]
475
+
476
+ if named:
477
+ tsp.name = self.name
478
+ tsp.ordinal = False
479
+ elif not named:
480
+ tsp.ordinal = True
481
+ return tsp
482
+
483
+ def _tspark_value_arg(self):
484
+ """Returns a TSparkParameterValueArg object that can be passed to the DBR thrift server."""
485
+ tva = TSparkParameterValueArg(type=self._cast_expr())
486
+ tva.arguments = [val._tspark_value_arg() for val in self.value]
487
+ return tva
488
+
489
+ CAST_EXPR = DatabricksSupportedType.ARRAY.name
490
+
491
+
492
+ class MapParameter(DbsqlParameterBase):
493
+ """Wrap a Python `dict` that will be bound to a Databricks SQL MAP type."""
494
+
495
+ def __init__(self, value: dict, name: Optional[str] = None):
496
+ """
497
+ :value:
498
+ The value to bind for this parameter. This will be casted to a MAP.
499
+ :name:
500
+ If None, your query must contain a `?` marker. Like:
501
+
502
+ ```sql
503
+ SELECT * FROM table WHERE field = ?
504
+ ```
505
+ If not None, your query should contain a named parameter marker. Like:
506
+ ```sql
507
+ SELECT * FROM table WHERE field = :my_param
508
+ ```
509
+
510
+ The `name` argument to this function would be `my_param`.
511
+ """
512
+ self.name = name
513
+ self.value = [
514
+ dbsql_parameter_from_primitive(item)
515
+ for key, val in value.items()
516
+ for item in (key, val)
517
+ ]
518
+
519
+ def as_tspark_param(self, named: bool = False) -> TSparkParameter:
520
+ """Returns a TSparkParameter object that can be passed to the DBR thrift server."""
521
+
522
+ tsp = TSparkParameter(type=self._cast_expr())
523
+ tsp.arguments = [val._tspark_value_arg() for val in self.value]
524
+ if named:
525
+ tsp.name = self.name
526
+ tsp.ordinal = False
527
+ elif not named:
528
+ tsp.ordinal = True
529
+ return tsp
530
+
531
+ def _tspark_value_arg(self):
532
+ """Returns a TSparkParameterValueArg object that can be passed to the DBR thrift server."""
533
+ tva = TSparkParameterValueArg(type=self._cast_expr())
534
+ tva.arguments = [val._tspark_value_arg() for val in self.value]
535
+ return tva
536
+
537
+ CAST_EXPR = DatabricksSupportedType.MAP.name
538
+
539
+
431
540
  class DecimalParameter(DbsqlParameterBase):
432
541
  """Wrap a Python `Decimal` that will be bound to a Databricks SQL DECIMAL type."""
433
542
 
@@ -543,23 +652,26 @@ def dbsql_parameter_from_primitive(
543
652
  # havoc. We can't use TYPE_INFERRENCE_MAP because mypy doesn't trust
544
653
  # its logic
545
654
 
546
- if type(value) is int:
655
+ if isinstance(value, bool):
656
+ return BooleanParameter(value=value, name=name)
657
+ elif isinstance(value, int):
547
658
  return dbsql_parameter_from_int(value, name=name)
548
- elif type(value) is str:
659
+ elif isinstance(value, str):
549
660
  return StringParameter(value=value, name=name)
550
- elif type(value) is float:
661
+ elif isinstance(value, float):
551
662
  return FloatParameter(value=value, name=name)
552
- elif type(value) is datetime.datetime:
663
+ elif isinstance(value, datetime.datetime):
553
664
  return TimestampParameter(value=value, name=name)
554
- elif type(value) is datetime.date:
665
+ elif isinstance(value, datetime.date):
555
666
  return DateParameter(value=value, name=name)
556
- elif type(value) is bool:
557
- return BooleanParameter(value=value, name=name)
558
- elif type(value) is decimal.Decimal:
667
+ elif isinstance(value, decimal.Decimal):
559
668
  return DecimalParameter(value=value, name=name)
669
+ elif isinstance(value, dict):
670
+ return MapParameter(value=value, name=name)
671
+ elif isinstance(value, Sequence) and not isinstance(value, str):
672
+ return ArrayParameter(value=value, name=name)
560
673
  elif value is None:
561
674
  return VoidParameter(value=value, name=name)
562
-
563
675
  else:
564
676
  raise NotSupportedError(
565
677
  f"Could not infer parameter type from value: {value} - {type(value)} \n"
@@ -581,6 +693,8 @@ TDbsqlParameter = Union[
581
693
  TimestampNTZParameter,
582
694
  TinyIntParameter,
583
695
  DecimalParameter,
696
+ ArrayParameter,
697
+ MapParameter,
584
698
  ]
585
699
 
586
700