Skip to content

Commit 9bfe41f

Browse files
jacalataclaude
andcommitted
feat: add database_name to ConnectionItem
Fixes #1571 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5d9a3c5 commit 9bfe41f

13 files changed

Lines changed: 112 additions & 18 deletions

tableauserverclient/datetime_helpers.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import datetime
22

3-
43
ZERO = datetime.timedelta(0)
54
HOUR = datetime.timedelta(hours=1)
65

tableauserverclient/helpers/strings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from functools import singledispatch
33
from typing import TypeVar, overload
44

5-
65
# the redact method can handle either strings or bytes, but it can't mix them.
76
# Generic type so we can write the actual logic once, then use singledispatch to
87
# create the replacement text with the correct type

tableauserverclient/models/column_item.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def from_response(cls, resp, ns):
5454
all_column_xml = parsed_response.findall(".//t:column", namespaces=ns)
5555

5656
for column_xml in all_column_xml:
57-
(id, name, description, remote_type) = cls._parse_element(column_xml, ns)
57+
id, name, description, remote_type = cls._parse_element(column_xml, ns)
5858
column_item = cls(name)
5959
column_item._set_values(id, name, description, remote_type)
6060
all_column_items.append(column_item)

tableauserverclient/models/connection_item.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ class ConnectionItem:
4747
The Connection Credentials object containing authentication details for
4848
the connection. Replaces username/password/embed_password when
4949
publishing a flow, document or workbook file in the request body.
50+
51+
database_name: str
52+
The name of the database for the connection.
5053
"""
5154

5255
def __init__(self):
@@ -62,6 +65,7 @@ def __init__(self):
6265
self.connection_credentials: ConnectionCredentials | None = None
6366
self._query_tagging: bool | None = None
6467
self._auth_type: str | None = None
68+
self._database_name: str | None = None
6569

6670
@property
6771
def datasource_id(self) -> str | None:
@@ -102,6 +106,14 @@ def auth_type(self) -> str | None:
102106
def auth_type(self, value: str | None):
103107
self._auth_type = value
104108

109+
@property
110+
def database_name(self) -> str | None:
111+
return self._database_name
112+
113+
@database_name.setter
114+
def database_name(self, value: str | None):
115+
self._database_name = value
116+
105117
def __repr__(self):
106118
return "<ConnectionItem#{_id} embed={embed_password} type={_connection_type} auth={_auth_type} username={username}>".format(
107119
**self.__dict__
@@ -124,6 +136,11 @@ def from_response(cls, resp, ns) -> list["ConnectionItem"]:
124136
string_to_bool(s) if (s := connection_xml.get("queryTagging", None)) else None
125137
)
126138
connection_item._auth_type = connection_xml.get("authenticationType", None)
139+
# The REST API GET /connections response uses "dbName" for the database
140+
# name attribute. This is different from the publish request body, which
141+
# uses "databaseName" (see _add_connections_element in request_factory.py).
142+
# Both names map to the same database_name property on ConnectionItem.
143+
connection_item._database_name = connection_xml.get("dbName", None)
127144
datasource_elem = connection_xml.find(".//t:datasource", namespaces=ns)
128145
if datasource_elem is not None:
129146
connection_item._datasource_id = datasource_elem.get("id", None)
@@ -152,6 +169,10 @@ def from_xml_element(cls, parsed_response, ns) -> list["ConnectionItem"]:
152169
connection_item.server_address = connection_xml.get("serverAddress", None)
153170
connection_item.server_port = connection_xml.get("serverPort", None)
154171
connection_item._auth_type = connection_xml.get("authenticationType", None)
172+
# Publish/update request bodies use "databaseName" (matching the
173+
# publish-request schema), while GET responses use "dbName". See
174+
# from_response() above and _add_connections_element() in request_factory.py.
175+
connection_item._database_name = connection_xml.get("databaseName", None)
155176

156177
connection_credentials = connection_xml.find(".//t:connectionCredentials", namespaces=ns)
157178

tableauserverclient/models/data_alert_item.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ def __init__(self):
3737

3838
def __repr__(self) -> str:
3939
return "<Data Alert {_id} subject={_subject} frequency={_frequency} \
40-
public={_public}>".format(
41-
**self.__dict__
42-
)
40+
public={_public}>".format(**self.__dict__)
4341

4442
@property
4543
def id(self) -> str | None:

tableauserverclient/models/subscription_item.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,10 @@ def __init__(self, subject: str, schedule_id: str, user_id: str, target: "Target
2929
def __repr__(self) -> str:
3030
if self.id is not None:
3131
return "<Subscription#{_id} subject({subject}) schedule_id({schedule_id}) user_id({user_id}) \
32-
target({target})".format(
33-
**self.__dict__
34-
)
32+
target({target})".format(**self.__dict__)
3533
else:
3634
return "<Subscription subject({subject}) schedule_id({schedule_id}) user_id({user_id}) \
37-
target({target})".format(
38-
**self.__dict__
39-
)
35+
target({target})".format(**self.__dict__)
4036

4137
@property
4238
def id(self):

tableauserverclient/server/endpoint/data_alert_endpoint.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
from typing import TYPE_CHECKING
1111

12-
1312
if TYPE_CHECKING:
1413
from ..server import Server
1514
from ..request_options import RequestOptions

tableauserverclient/server/endpoint/schedules_endpoint.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ def add_to_schedule(
226226
task_type = TaskItem.Type.RunFlow
227227
items.append(
228228
(schedule_id, flow, "flow", RequestFactory.Schedule.add_flow_req, task_type)
229-
) # type:ignore[arg-type]
229+
) # type: ignore[arg-type]
230230

231231
results = (self._add_to(*x) for x in items)
232232
return [x for x in results if not x.result]

tableauserverclient/server/pager.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from tableauserverclient.models.pagination_item import PaginationItem
77
from tableauserverclient.server.request_options import RequestOptions
88

9-
109
T = TypeVar("T")
1110

1211

tableauserverclient/server/request_factory.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ def _add_connections_element(connections_element, connection):
4747
connection_element.attrib["serverAddress"] = connection.server_address
4848
if connection.server_port:
4949
connection_element.attrib["serverPort"] = connection.server_port
50+
if connection.database_name:
51+
connection_element.attrib["databaseName"] = connection.database_name
5052
if connection.connection_credentials:
5153
connection_credentials = connection.connection_credentials
5254
elif connection.username is not None and connection.password is not None and connection.embed_password is not None:
@@ -611,7 +613,7 @@ def update_req(self, schedule_item):
611613
intervals_element = ET.SubElement(frequency_element, "intervals")
612614
if hasattr(interval_item, "interval"):
613615
for interval in interval_item._interval_type_pairs():
614-
(expression, value) = interval
616+
expression, value = interval
615617
single_interval_element = ET.SubElement(intervals_element, "interval")
616618
single_interval_element.attrib[expression] = value
617619
return ET.tostring(xml_request)

0 commit comments

Comments
 (0)