Closed tableaukun closed 6 years ago
Looks like return rel_xml_obj
needs to be called out twice in the code.
def generate_relation_section(self):
# Because of the strange way that the interior definition is the last on, you need to work inside out
# "Middle-out" as Silicon Valley suggests.
# Generate the actual JOINs
#if self.relation_xml_obj is not None:
# self.relation_xml_obj.clear()
#else:
rel_xml_obj = etree.Element(u"relation")
# There's only a single main relation with only one table
if len(self.join_relations) == 0:
for item in self.main_table_relation.items():
rel_xml_obj.set(item[0], item[1])
if self.main_table_relation.text is not None:
rel_xml_obj.text = self.main_table_relation.text
return rel_xml_obj ###THIS WAS MISSING
else:
prev_relation = rel_xml_obj
# We go through each relation, build the whole thing, then append it to the previous relation, then make
# that the new prev_relationship. Something like recursion
for join_desc in self.join_relations:
r = etree.Element(u"relation")
r.set(u"join", join_desc[u"join_type"])
r.set(u"type", u"join")
if len(join_desc[u"on_clauses"]) == 0:
raise InvalidOptionException("Join clause must have at least one ON clause describing relation")
else:
and_expression = None
if len(join_desc[u"on_clauses"]) > 1:
and_expression = etree.Element(u"expression")
and_expression.set(u"op", u'AND')
for on_clause in join_desc[u"on_clauses"]:
c = etree.Element(u"clause")
c.set(u"type", u"join")
e = etree.Element(u"expression")
e.set(u"op", on_clause[u"operator"])
e_field1 = etree.Element(u"expression")
e_field1_name = u'[{}].[{}]'.format(on_clause[u"left_table_alias"],
on_clause[u"left_field"])
e_field1.set(u"op", e_field1_name)
e.append(e_field1)
e_field2 = etree.Element(u"expression")
e_field2_name = u'[{}].[{}]'.format(on_clause[u"right_table_alias"],
on_clause[u"right_field"])
e_field2.set(u"op", e_field2_name)
e.append(e_field2)
if and_expression is not None:
and_expression.append(e)
else:
and_expression = e
c.append(and_expression)
r.append(c)
r.append(prev_relation)
if join_desc[u"custom_sql"] is None:
new_table_rel = self.create_table_relation(join_desc[u"db_table_name"],
join_desc[u"table_alias"])
elif join_desc[u"custom_sql"] is not None:
new_table_rel = self.create_custom_sql_relation(join_desc[u'custom_sql'],
join_desc[u'table_alias'])
r.append(new_table_rel)
prev_relation = r
rel_xml_obj.append(prev_relation)
return rel_xml_obj
I've fixed this by moving the return out of the else loop so that it will return under either condition. Thank you for finding and determining a fix. I've checked into the code for 4.6.2 and will close this when it is fully released
Version 4.6.2 is now released with a fix for this issue. Please reopen if the issue persists.
tableau_tools Version = 4.6.0 Python Version = 2.7.10 OS Version = macOS High Sierra 10.13.3 Tableau Server Version = 10.5
I followed the docs to create a data source from scratch, but keep running into errors. When trying to create one with a Custom SQL Query, I get an Element error. Below is my code:
There seems to be an issue with
generate_relation_section()
. I manually ran the code for the function and received the expected value: