Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
olapy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
2
Merge Requests
2
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
olapy
Commits
64486df0
Commit
64486df0
authored
Mar 17, 2017
by
Stefane Fermigier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
"On rows".
parent
26bd503c
Changes
5
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
439 additions
and
255 deletions
+439
-255
olapy/core/mdx/executor/execute.py
olapy/core/mdx/executor/execute.py
+78
-32
olapy/core/services/xmla.py
olapy/core/services/xmla.py
+20
-13
olapy/core/services/xmla_discover_tools.py
olapy/core/services/xmla_discover_tools.py
+69
-47
olapy/core/services/xmla_execute_tools.py
olapy/core/services/xmla_execute_tools.py
+272
-161
tests/test_xmla_notox.py
tests/test_xmla_notox.py
+0
-2
No files found.
olapy/core/mdx/executor/execute.py
View file @
64486df0
...
...
@@ -127,6 +127,23 @@ class MdxEngine:
"""
return
os
.
path
.
join
(
self
.
cube_path
,
self
.
cube
)
# TODO temporary function
def
get_tuples
(
self
,
query
,
start
=
None
,
stop
=
None
):
# TODO use grako instead and remove regex
regex
=
"(
\
[[
\
w
\
d ]+
\
](
\
.
\
[[
\
w
\
d
\
.
\
- ]+
\
])*
\
.?((Members)|(
\
[Q
\
d
\
]))?)
"
if start is not None:
start = query.index(start)
if stop is not None:
stop = query.index(stop)
# clean the query (from All, Members...)
return [[
tup_att.replace('All ', '').replace('[', "").replace("
]
", "")
for tup_att in tup[0].replace('.Members', '').split('.')
] for tup in re.compile(regex).findall(query[start:stop])
if len(tup[0].split('.')) > 1]
# TODO temporary function
def decorticate_query(self, query):
"""
...
...
@@ -135,16 +152,38 @@ class MdxEngine:
:return: all tuples in the query
"""
# TODO use grako instead and remove regex
regex
=
"(
\
[[
\
w
\
d ]+
\
](
\
.
\
[[
\
w
\
d
\
.
\
- ]+
\
])*
\
.?((Members)|(
\
[Q
\
d
\
]))?)
"
# clean the query
tuples_on_mdx_query = [[
tup_att.replace('All ', '').replace('[', "").replace("
]
", "")
for tup_att in tup[0].replace('.Members', '').split('.')
] for tup in re.compile(regex).findall(query)
if len(tup[0].split('.')) > 1]
tuples_on_mdx_query = self.get_tuples(query)
return tuples_on_mdx_query
on_rows = []
on_columns = []
on_where = []
# ON ROWS
if 'ON ROWS' in query:
stop = 'ON ROWS'
if 'ON COLUMNS' in query:
start = 'ON COLUMNS'
else:
start = 'SELECT'
on_rows = self.get_tuples(query, start, stop)
# ON COLUMNS
if 'ON COLUMNS' in query:
start = 'SELECT'
stop = 'ON COLUMNS'
on_columns = self.get_tuples(query, start, stop)
# WHERE
if 'WHERE' in query:
start = 'FROM'
on_where = self.get_tuples(query, start)
return {
'all': tuples_on_mdx_query,
'columns': on_columns,
'rows': on_rows,
'where': on_where
}
def change_measures(self, tuples_on_mdx):
"""
...
...
@@ -161,6 +200,7 @@ class MdxEngine:
]
def get_tables_and_columns(self, tuple_as_list):
# TODO update docstring
"""
get used dimensions and columns in the MDX Query (useful for DataFrame -> xmla response transformation)
...
...
@@ -178,23 +218,31 @@ class MdxEngine:
Facts : ['Amount','Count']
}
"""
tables_columns = OrderedDict()
axes = {}
# TODO optimize
for axis, tuples in tuple_as_list.items():
measures = []
for tupl in tuple_as_list:
tables_columns = OrderedDict()
# if we have measures in columns or rows axes like :
# SELECT {[Measures].[Amount],[Measures].[Count]} ON COLUMNS
# we have to add measures directly to tables_columns
for tupl in tuples:
if tupl[0].upper() == 'MEASURES':
if tupl[-1] not in measures:
measures.append(tupl[-1])
tables_columns.update({self.facts: measures})
else:
continue
else:
tables_columns.update({
tupl[0]:
self.tables_loaded[tupl[0]].columns[:len(tupl[2:])]
})
return tables_columns
axes.update({axis: tables_columns})
return axes
def execute_one_tuple(self, tuple_as_list, Dataframe_in, columns_to_keep):
"""
...
...
@@ -397,24 +445,21 @@ class MdxEngine:
"""
# use measures that exists on where or insides axes
all_tupl
es = self.decorticate_query(self.mdx_query)
query_ax
es = self.decorticate_query(self.mdx_query)
if self.change_measures(
all_tuples
):
self.measures = self.change_measures(
all_tuples
)
if self.change_measures(
query_axes['all']
):
self.measures = self.change_measures(
query_axes['all']
)
# get only used columns and dimensions for all query
start_df = self.load_star_schema_dataframe
tables_n_columns = self.get_tables_and_columns(
all_tupl
es)
tables_n_columns = self.get_tables_and_columns(
query_ax
es)
columns_to_keep = {
table: columns
for table, columns in tables_n_columns.items()
if table != self.facts
}
columns_to_keep = OrderedDict(
(table, columns) for table, columns in tables_n_columns['all'].items() if table != self.facts)
# if we have measures on axes we have to ignore them
tuples_on_mdx_query = [
tup for tup in
all_tuples
if tup[0].upper() != 'MEASURES'
tup for tup in
query_axes['all']
if tup[0].upper() != 'MEASURES'
]
# if we have tuples in axes
# to avoid prob with query like this: SELECT FROM [Sales] WHERE ([Measures].[Amount])
...
...
@@ -469,6 +514,7 @@ class MdxEngine:
df = pd.concat(self.add_missed_column(df, next_df))
# TODO groupby in web demo (remove it for more performance)
# TODO margins=True for columns total !!!!!
return {
'result':
df.drop_duplicates().replace(np.nan, -1).groupby(cols).sum(),
...
...
olapy/core/services/xmla.py
View file @
64486df0
...
...
@@ -81,22 +81,27 @@ class XmlaProviderService(ServiceBase):
return
discover_tools
.
discover_mdschema_measures__response
(
request
)
elif
request
.
RequestType
==
"MDSCHEMA_DIMENSIONS"
:
return
discover_tools
.
discover_mdschema_dimensions_response
(
request
)
return
discover_tools
.
discover_mdschema_dimensions_response
(
request
)
elif
request
.
RequestType
==
"MDSCHEMA_HIERARCHIES"
:
return
discover_tools
.
discover_mdschema_hierarchies_response
(
request
)
return
discover_tools
.
discover_mdschema_hierarchies_response
(
request
)
elif
request
.
RequestType
==
"MDSCHEMA_LEVELS"
:
return
discover_tools
.
discover_mdschema_levels__response
(
request
)
elif
request
.
RequestType
==
"MDSCHEMA_MEASUREGROUPS"
:
return
discover_tools
.
discover_mdschema_measuresgroups_response
(
request
)
return
discover_tools
.
discover_mdschema_measuresgroups_response
(
request
)
elif
request
.
RequestType
==
"MDSCHEMA_MEASUREGROUP_DIMENSIONS"
:
return
discover_tools
.
discover_mdschema_measuresgroups_dimensions_response
(
request
)
return
discover_tools
.
discover_mdschema_measuresgroups_dimensions_response
(
request
)
elif
request
.
RequestType
==
"MDSCHEMA_PROPERTIES"
:
return
discover_tools
.
discover_mdschema_properties_response
(
request
)
return
discover_tools
.
discover_mdschema_properties_response
(
request
)
elif
request
.
RequestType
==
"MDSCHEMA_MEMBERS"
:
return
discover_tools
.
discover_mdschema_members_response
(
request
)
...
...
@@ -127,7 +132,8 @@ class XmlaProviderService(ServiceBase):
</return>
"""
)
else
:
XmlaProviderService
.
discover_tools
.
change_catalogue
(
request
.
Properties
.
PropertyList
.
Catalog
)
XmlaProviderService
.
discover_tools
.
change_catalogue
(
request
.
Properties
.
PropertyList
.
Catalog
)
executer
=
XmlaProviderService
.
discover_tools
.
executer
executer
.
mdx_query
=
request
.
Command
.
Statement
df
=
executer
.
execute_mdx
()
...
...
@@ -143,33 +149,34 @@ class XmlaProviderService(ServiceBase):
<Cube>
<CubeName>Sales</CubeName>
<LastDataUpdate
xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">{
6
}</LastDataUpdate>
xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">{
7
}</LastDataUpdate>
<LastSchemaUpdate
xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">{
6
}</LastSchemaUpdate>
xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">{
7
}</LastSchemaUpdate>
</Cube>
</CubeInfo>
<AxesInfo>
{1}
</AxesInfo>
{2}
</AxesInfo>
{3}
</OlapInfo>
<Axes>
{3}
{4}
{5}
</Axes>
<CellData>
{
5
}
{
6
}
</CellData>
</root>
</return>
"""
.
format
(
execute_xsd
,
xmla_tools
.
generate_axes_info
(
df
),
xmla_tools
.
generate_axes_info_slicer
(
df
),
xmla_tools
.
generate_cell_info
(),
xmla_tools
.
generate_xs0
(
df
),
xmla_tools
.
generate_slicer_axis
(
df
),
xmla_tools
.
generate_cell_data
(
df
),
datetime
.
now
().
strftime
(
'%Y-%m-%dT%H:%M:%S'
)
))
datetime
.
now
().
strftime
(
'%Y-%m-%dT%H:%M:%S'
)))
application
=
Application
(
...
...
olapy/core/services/xmla_discover_tools.py
View file @
64486df0
This diff is collapsed.
Click to expand it.
olapy/core/services/xmla_execute_tools.py
View file @
64486df0
This diff is collapsed.
Click to expand it.
tests/test_xmla_notox.py
View file @
64486df0
...
...
@@ -266,8 +266,6 @@ def test_query2(conn):
DisplayInfo
=
'131076'
,
PARENT_UNIQUE_NAME
=
'[Geography].[Geography].[Continent].[Europe]'
,
HIERARCHY_UNIQUE_NAME
=
'[Geography].[Geography]'
))
print
([
Member
(
**
dict
(
co
))
for
co
in
columns
])
print
(
mems
)
assert
[
Member
(
**
dict
(
co
))
for
co
in
columns
]
==
mems
assert
values
==
[
768
,
768
,
768
,
255
,
4
,
3
,
2
,
1
,
248
]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment