From 0491bcaae22b0101c8f6942c531c8ee16ed0123d Mon Sep 17 00:00:00 2001 From: Sergey Batishchev Date: Wed, 23 Dec 2020 16:34:27 +0300 Subject: [PATCH] Fixed tabular mode --- xmla/olap/xmla/connection.py | 9 +++++++-- xmla/olap/xmla/formatreader.py | 24 +++++++++++++++++++++++- xmla/olap/xmla/utils.py | 6 +++--- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/xmla/olap/xmla/connection.py b/xmla/olap/xmla/connection.py index b105680..49e48fe 100644 --- a/xmla/olap/xmla/connection.py +++ b/xmla/olap/xmla/connection.py @@ -9,7 +9,7 @@ from zeep.transports import Transport #import types -from .formatreader import TupleFormatReader +from .formatreader import TupleFormatReader, TupleFormatReaderTabular from .utils import * import logging @@ -21,6 +21,7 @@ schema_xmla_rowset="urn:schemas-microsoft-com:xml-analysis:rowset" schema_xmla_mddataset="urn:schemas-microsoft-com:xml-analysis:mddataset" schema_soap_env="http://schemas.xmlsoap.org/soap/envelope/" +schema_xml="http://www.w3.org/2001/XMLSchema" # the following along with changes to the wsdl (elementFormDefault="unqualified") is needed # to make it fly with icCube, which expects elements w/o namespace prefix @@ -169,11 +170,15 @@ def Execute(self, command, dimformat="Multidimensional", props.update(kwargs) plist = as_etree({"PropertyList":props}) + ns = schema_xmla_mddataset if dimformat == "Multidimensional" else schema_xmla_rowset + reader = TupleFormatReader if dimformat == "Multidimensional" else TupleFormatReaderTabular try: res = self.service.Execute(Command=command, Properties=plist, _soapheaders=self._soapheaders) root = res.body["return"]["_value_1"] - return TupleFormatReader(fromETree(root, ns=schema_xmla_mddataset)) + cols = None if dimformat == "Multidimensional" else fromETree(root, ns=schema_xml, name="schema") + rows = fromETree(root, ns=ns) + return reader(rows, cols) except Fault as fault: raise XMLAException(fault.message, dictify(fromETree(fault.detail, ns=None))) diff --git a/xmla/olap/xmla/formatreader.py b/xmla/olap/xmla/formatreader.py index ced5e56..65bcbd7 100644 --- a/xmla/olap/xmla/formatreader.py +++ b/xmla/olap/xmla/formatreader.py @@ -6,8 +6,9 @@ @zope.interface.implementer(IMDXResult) class TupleFormatReader(object): - def __init__(self, tupleresult): + def __init__(self, tupleresult, cols=None): self.root = tupleresult + self.cols = cols self.cellmap = self.mapOrdinalsToCells() def mapOrdinalsToCells(self): @@ -169,3 +170,24 @@ def getSlice(self, properties=None, **kw): # so we can safely unpack the first element # in that element our resulting multidimensional array has been accumulated return axisranges[lastdimchange-1][1][0] + + +class TupleFormatReaderTabular(object): + + def __init__(self, tupleresult, cols=None): + self.root = tupleresult + self.colmap = {obj['_name']: obj['_{urn:schemas-microsoft-com:xml-sql}field'] + for obj in list(filter(lambda x: x['_name'] == 'row', + cols['schema']['complexType']))[0]['sequence']['element']} + + def items(self): + rows = self.root['row'] + if not isinstance(rows, list): + rows = [rows] + for row in rows: + item = {} + for key, value in row.items(): + if key in self.colmap: + item[self.colmap[key]] = value + + yield item diff --git a/xmla/olap/xmla/utils.py b/xmla/olap/xmla/utils.py index ff614aa..8c0da78 100644 --- a/xmla/olap/xmla/utils.py +++ b/xmla/olap/xmla/utils.py @@ -136,9 +136,9 @@ def ns_name(ns, name): return name return "{{{}}}{}".format(ns,name) -def fromETree(e, ns): +def fromETree(e, ns=None, name=None): p = Data() - nst = ns_name(ns, "*") + nst = ns_name(ns, name or "*") valtype = ns_name(schema_instance, "type") for (k,v) in e.attrib.items(): setattr(p, "_"+k, v) @@ -169,4 +169,4 @@ def fromETree(e, ns): getattr(p, t.localname).append(cd) else: setattr(p, t.localname, cd) - return p \ No newline at end of file + return p