8000 added support for generating query for federated connections · kgtdbx/document-api-python@d51a3e7 · GitHub
[go: up one dir, main page]

Skip to content

Commit d51a3e7

Browse files
author
Richard Kooijman
committed
added support for generating query for federated connections
1 parent b5760cb commit d51a3e7

File tree

9 files changed

+33018
-3
lines changed

9 files changed

+33018
-3
lines changed

samples/connection-query/Cash Register.tds

Lines changed: 8584 additions & 0 deletions
Large diffs are not rendered by default.

samples/connection-query/Sales.tds

Lines changed: 24299 additions & 0 deletions
Large diffs are not rendered by default.

samples/connection-query/show_sql.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from tableaudocumentapi import Datasource
2+
3+
sourceTDS = Datasource.from_file('Sales.tds')
4+
5+
print(sourceTDS.get_query())
6+
7+
sourceTDS = Datasource.from_file('Cash Register.tds')
8+
9+
print(sourceTDS.get_query())

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name='tableaudocumentapi',
8-
version='0.8',
8+
version='0.9',
99
author='Tableau',
1010
author_email='github@tableau.com',
1111
url='https://github.com/tableau/document-api-python',

tableaudocumentapi/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
from .field import Field
2+
from .expression import Expression
3+
from .clause import Clause
4+
from .relation import Relation
25
from .db_column import DBColumn
36
from .connection import Connection
47
from .parameter import Parameter
58
from .datasource import Datasource, ConnectionParser, ParameterParser
69
from .workbook import Workbook
710

8-
__version__ = '0.8.0'
11+
__version__ = '0.9.0'
912
__VERSION__ = __version__

tableaudocumentapi/clause.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from tableaudocumentapi import Expression
2+
3+
class Clause(object):
4+
"""A class representing clauses inside Relations."""
5+
6+
def __init__(self, clause_xml):
7+
"""Clause is usually instantiated by passing in relation XML
8+
from a Connection.
9+
"""
10+
self._clauseXML = clause_xml
11+
self._type = clause_xml.get('type')
12+
self._expressions = list(map(Expression, self._clauseXML.findall('./expression')))
13+
14+
@property
15+
def type(self):
16+
return self._type
17+
18+
@property
19+
def expression(self):
20+
return self._expression
21+
22+
def __str__(self):
23+
if self.type == "join":
24+
return f"{self._expressions[0]}"
25+
return "ERROR"

tableaudocumentapi/datasource.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
from uuid import uuid4
66

77
from tableaudocumentapi import Connection, xfile
8-
from tableaudocumentapi import Field, DBColumn, Parameter
8+
from tableaudocumentapi import Field, DBColumn, Parameter, Relation
99
from tableaudocumentapi.multilookup_dict import MultiLookupDict
1010
from tableaudocumentapi.xfile import xml_open
1111

12+
1213
########
1314
# This is needed in order to determine if something is a string or not. It is necessary because
1415
# of differences between python2 (basestring) and python3 (str). If python2 support is ever
@@ -162,6 +163,8 @@ def __init__(self, dsxml, filename=None):
162163
self._columns = None
163164
self._db_columns = self._get_db_column_objects()
164165

166+
self._relations = list(map(Relation, self._datasourceXML.findall('./connection/relation')))
167+
165168
@classmethod
166169
def from_file(cls, filename):
167170
"""Initialize datasource from file (.tds ot .tdsx)"""
@@ -310,3 +313,6 @@ def process_columns(self):
310313
x = Field.create_field_xml(field.id, field.caption, field.datatype, field.role, field.type)
311314
Field.set_description(field.description, x)
312315
self._datasourceXML.insert(column_index, x)
316+
317+
def get_query(self):
318+
return f"{self._relations[0]}"

tableaudocumentapi/expression.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
class Expression(object):
2+
"""A class representing expression inside Data Sources."""
3+
4+
_LOGICALS = [
5+
'AND',
6+
'OR'
7+
]
8+
9+
_COMPARISONS = [
10+
'=',
11+
'>',
12+
'>=',
13+
'<',
14+
'<=',
15+
'!=',
16+
'<>'
17+
]
18+
19+
_OPS = _LOGICALS + _COMPARISONS
20+
21+
def __init__(self, expression_xml):
22+
"""Expression is usually instantiated by passing in expression XML
23+
from a Relation.
24+
"""
25+
self._expressionXML = expression_xml
26+
self._op = expression_xml.get('op')
27+
self._expressions = list(map(Expression, self._expressionXML.findall('./expression')))
28+
29+
@property
30+
def op(self):
31+
return self._op
32+
33+
@property
34+
def expressions(self):
35+
return self._expressions
36+
37+
def __str__(self):
38+
if self.op in Expression._LOGICALS:
3 10000 9+
return (" " + self.op + " ").join(map(str, self._expressions))
40+
if self.op in Expression._COMPARISONS:
41+
return f"{self._expressions[0]} {self.op} {self._expressions[1]}"
42+
if len(self._expressions) == 0:
43+
return f"{self.op}"
44+
return "ERROR"

tableaudocumentapi/relation.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from tableaudocumentapi import Clause
2+
3+
class Relation(object):
4+
"""A class representing parameters inside Data Sources."""
5+
6+
def __init__(self, relation_xml):
7+
"""Relation is usually instantiated by passing in relation XML
8+
from a Connection.
9+
"""
10+
self._relationXML = relation_xml
11+
self._type = relation_xml.get('type')
12+
self._join = relation_xml.get('join')
13+
self._name = relation_xml.get('name')
14+
self._table = relation_xml.get('table')
15+
self._connection = relation_xml.get('connection')
16+
17+
self._clause = list(map(Clause, self._relationXML.findall('./clause')))
18+
self._relations = list(map(Relation, self._relationXML.findall('./relation')))
19+
20+
@property
21+
def type(self):
22+
return self._type
23+
24+
@property
25+
def join(self):
26+
return self._join
27+
28+
@property
29+
def name(self):
30+
return self._name
31+
32+
@property
33+
def table(self):
34+
return self._table
35+
36+
@property
37+
def connection(self):
38+
return self._connection
39+
40+
def __str__(self):
41+
if self.type == "table":
42+
return f'{self.table} "{self.name}"'
43+
if self.type == "join":
44+
return f"{self._relations[0]} {self.join} {self.type} {self._relations[1]} on ({self._clause[0]})"
45+
return "ERROR"

0 commit comments

Comments
 (0)
0