10000 Refactors suggested in last PR. Now there is a connections property t… · dmgactive/document-api-python@7983772 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7983772

Browse files
committed
Refactors suggested in last PR. Now there is a connections property that always returns a list of connections. In the legacy case it's just a list of one, in the federated case it's all of them (in order they are in the twb). This gives folks a consistent API. Updated tests to match, and the example and README as well
1 parent a22d077 commit 7983772

File tree

5 files changed

+55
-33
lines changed

5 files changed

+55
-33
lines changed

Examples/Replicate Workbook/replicateWorkbook.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
databases = csv.DictReader(csvfile, delimiter=',', quotechar='"')
1919
for row in databases:
2020
# Set our unique values for this database
21-
sourceWB.datasources[0].connection.server = row['Server']
22-
sourceWB.datasources[0].connection.dbname = row['Database']
23-
sourceWB.datasources[0].connection.username = row['User']
21+
sourceWB.datasources[0].connections[0].server = row['Server']
22+
sourceWB.datasources[0].connections[0].dbname = row['Database']
23+
sourceWB.datasources[0].connections[0].username = row['User']
2424
# Save our newly created .twb with the new file name
2525
sourceWB.save_as(row['DBFriendlyName'] + ' - Superstore' + '.twb')

README.md

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ We don't yet support creating files from scratch. In addition, support for `.twb
1616

1717

1818
###Getting Started
19-
To use this SDK, you must have Python installed. You can use either 2.7x or 3.3x.
19+
To use this SDK, you must have Python installed. You can use either 2.7.X or 3.3 and later.
2020

2121
Download the `.zip` file that contains the SDK. Unzip the file and then run the following command:
2222

2323
```text
2424
pip install -e <directory containing setup.py>
2525
```
2626

27-
We plan on putting the package in PyPi to make installation easier.
27+
We plan on putting the package in PyPi to make installation easier.
2828

2929

3030
###Basics
@@ -35,23 +35,43 @@ from tableaudocumentapi import Workbook
3535

3636
sourceWB = Workbook('WorkbookToUpdate.twb')
3737

38-
sourceWB.datasources[0].connection.server = "MY-NEW-SERVER"
39-
sourceWB.datasources[0].connection.dbname = "NEW-DATABASE"
40-
sourceWB.datasources[0].connection.username = "benl"
38+
sourceWB.datasources[0].connections[0].server = "MY-NEW-SERVER"
39+
sourceWB.datasources[0].connections[0].dbname = "NEW-DATABASE"
40+
sourceWB.datasources[0].connections[0].username = "benl"
4141

4242
sourceWB.save()
4343
```
4444

45+
With Data Integration in Tableau 10, a datasource can have multiple connections. To access the connections simply index them like you would datasources
46+
47+
```python
48+
from tableaudocumentapi import Workbook
49+
50+
sourceWB = Workbook('WorkbookToUpdate.twb')
51+
52+
sourceWB.datasources[0].connections[0].server = "MY-NEW-SERVER"
53+
sourceWB.datasources[0].connections[0].dbname = "NEW-DATABASE"
54+
sourceWB.datasources[0].connections[0].username = "benl"
55+
56+
sourceWB.datasources[0].connections[1].server = "MY-NEW-SERVER"
57+
sourceWB.datasources[0].connections[1].dbname = "NEW-DATABASE"
58+
sourceWB.datasources[0].connections[1].username = "benl"
59+
60+
61+
sourceWB.save()
62+
```
63+
64+
4565
**Notes**
4666

4767
- Import the `Workbook` object from the `tableaudocumentapi` module.
4868
- To open a workbook, instantiate a `Workbook` object and pass the `.twb` file name in the constructor.
4969
- The `Workbook` object exposes a `datasources` collection.
50-
- Each datasource object has a `connection` object that supports a `server`, `dbname`, and `username` property.
51-
- Save changes to the workbook by calling the `save` or `save_as` method.
70+
- Each datasource object has a `connection` object that supports a `server`, `dbname`, and `username` property.
71+
- Save changes to the workbook by calling the `save` or `save_as` method.
5272

5373

5474

5575
###Examples
5676

57-
The downloadable package contains an example named `replicateWorkbook.py` (in the folder `\Examples\Replicate Workbook`). This example reads an existing workbook and reads a .csv file that contains a list of servers, database names, and users. For each new user in the .csv file, the code copies the original workbook, updates the `server`, `dbname`, and `username` properties, and saves the workbook under a new name.
77+
The downloadable package contains an example named `replicateWorkbook.py` (in the folder `\Examples\Replicate Workbook`). This example reads an existing workbook and reads a .csv file that contains a list of servers, database names, and users. For each new user in the .csv file, the code copies the original workbook, updates the `server`, `dbname`, and `username` properties, and saves the workbook under a new name.

tableaudocumentapi/datasource.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@
66
import xml.etree.ElementTree as ET
77
from tableaudocumentapi import Connection
88

9+
910
class ConnectionParser(object):
1011

1112
def __init__(self, datasource_xml, version):
1213
self._dsxml = datasource_xml
1314
self._dsversion = version
1415

1516
def _extract_federated_connections(self):
16-
return list(map(Connection,self._dsxml.findall('.//named-connections/named-connection/*')))
17+
return list(map(Connection, self._dsxml.findall('.//named-connections/named-connection/*')))
1718

1819
def _extract_legacy_connection(self):
19-
return Connection(self._dsxml.find('connection'))
20+
return list(map(Connection, self._dsxml.findall('connection')))
2021

2122
def get_connections(self):
2223
if float(self._dsversion) < 10:
@@ -45,10 +46,12 @@ def __init__(self, dsxml, filename=None):
4546
self._filename = filename
4647
self._datasourceXML = dsxml
4748
self._datasourceTree = ET.ElementTree(self._datasourceXML)
48-
self._name = self._datasourceXML.get('name') or self._datasourceXML.get('formatted-name') # TDS files don't have a name attribute
49+
self._name = self._datasourceXML.get('name') or self._datasourceXML.get(
50+
'formatted-name') # TDS files don't have a name attribute
4951
self._version = self._datasourceXML.get('version')
50-
self._connection_parser = ConnectionParser(self._datasourceXML, version=self._version)
51-
self._connection = self._connection_parser.get_connections()
52+
self._connection_parser = ConnectionParser(
53+
self._datasourceXML, version=self._version)
54+
self._connections = self._connection_parser.get_connections()
5255

5356
@classmethod
5457
def from_file(cls, filename):
@@ -84,7 +87,6 @@ def save_as(self, new_filename):
8487
"""
8588
self._datasourceTree.write(new_filename)
8689

87-
8890
###########
8991
# name
9092
###########
@@ -103,5 +105,5 @@ def version(self):
103105
# connection
104106
###########
105107
@property
106-
def connection(self):
107-
return self._connection
108+
def connections(self):
109+
return self._connections

tableaudocumentapi/workbook.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ def save_as(self, new_filename):
9292

9393
self._workbookTree.write(new_filename)
9494

95-
9695
###########################################################################
9796
#
9897
# Private API.
@@ -112,4 +111,3 @@ def _prepare_datasources(self, xmlRoot):
112111
def _is_valid_file(filename):
113112
fileExtension = os.path.splitext(filename)[-1].lower()
114113
return fileExtension in ('.twb', '.tds')
115-

test.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ class ConnectionParserTests(unittest.TestCase):
3434

3535
def test_can_extract_legacy_connection(self):
3636
parser = ConnectionParser(ET.fromstring(TABLEAU_93_TDS), '9.2')
37-
connection = parser.get_connections()
38-
self.assertIsInstance(connection, Connection)
39-
self.assertEqual(connection.dbname, 'TestV1')
37+
connections = parser.get_connections()
38+
self.assertIsInstance(connections, list)
39+
self.assertIsInstance(connections[0], Connection)
40+
self.assertEqual(connections[0].dbname, 'TestV1')
4041

4142

4243
def test_can_extract_federated_connections(self):
@@ -85,15 +86,16 @@ def test_can_extract_datasource_from_file(self):
8586

8687
def test_can_extract_connection(self):
8788
ds = Datasource.from_file(self.tds_file.name)
88-
self.assertIsInstance(ds.connection, Connection)
89+
self.assertIsInstance(ds.connections[0], Connection)
90+
self.assertIsInstance(ds.connections, list)
8991

9092
def test_can_save_tds(self):
9193
original_tds = Datasource.from_file(self.tds_file.name)
92-
original_tds.connection.dbname = 'newdb.test.tsi.lan'
94+
original_tds.connections[0].dbname = 'newdb.test.tsi.lan'
9395
original_tds.save()
9496

9597
new_tds = Datasource.from_file(self.tds_file.name)
96-
self.assertEqual(new_tds.connection.dbname, 'newdb.test.tsi.lan')
98+
self.assertEqual(new_tds.connections[0].dbname, 'newdb.test.tsi.lan')
9799

98100

99101
class WorkbookModelTests(unittest.TestCase):
@@ -116,11 +118,11 @@ def test_can_extract_datasource(self):
116118

117119
def test_can_update_datasource_connection_and_save(self):
118120
original_wb = Workbook(self.workbook_file.name)
119-
original_wb.datasources[0].connection.dbname = 'newdb.test.tsi.lan'
121+
original_wb.datasources[0].connections[0].dbname = 'newdb.test.tsi.lan'
120122
original_wb.save()
121123

122124
new_wb = Workbook(self.workbook_file.name)
123-
self.assertEqual(new_wb.datasources[0].connection.dbname, 'newdb.test.tsi.lan')
125+
self.assertEqual(new_wb.datasources[0].connections[0].dbname, 'newdb.test.tsi.lan')
124126

125127

126128
class WorkbookModelV10Tests(unittest.TestCase):
@@ -137,20 +139,20 @@ def tearDown(self):
137139
def test_can_extract_datasourceV10(self):
138140
wb = Workbook(self.workbook_file.name)
139141
self.assertEqual(len(wb.datasources), 1)
140-
self.assertEqual(len(wb.datasources[0].connection), 2)
141-
self.assertIsInstance(wb.datasources[0].connection, list)
142+
self.assertEqual(len(wb.datasources[0].connections), 2)
143+
self.assertIsInstance(wb.datasources[0].connections, list)
142144
self.assertIsInstance(wb.datasources[0], Datasource)
143145
self.assertEqual(wb.datasources[0].name,
144146
'federated.1s4nxn20cywkdv13ql0yk0g1mpdx')
145147

146148
def test_can_update_datasource_connection_and_saveV10(self):
147149
original_wb = Workbook(self.workbook_file.name)
148-
original_wb.datasources[0].connection[0].dbname = 'newdb.test.tsi.lan'
150+
original_wb.datasources[0].connections[0].dbname = 'newdb.test.tsi.lan'
149151

150152
original_wb.save()
151153

152154
new_wb = Workbook(self.workbook_file.name)
153-
self.assertEqual(new_wb.datasources[0].connection[0].dbname, 'newdb.test.tsi.lan')
155+
self.assertEqual(new_wb.datasources[0].connections[0].dbname, 'newdb.test.tsi.lan')
154156

155157
if __name__ == '__main__':
156158
unittest.main()

0 commit comments

Comments
 (0)
0