1-
21import re
32import traceback
43import typer
76
87from lkml2cube .parser .views import parse_view
98
10- snake_case = r'\{([a-zA-Z]+(?:_[a-zA-Z]+)*\.[a-zA-Z]+(?:_[a-zA-Z]+)*)\}'
9+ snake_case = r"\{([a-zA-Z]+(?:_[a-zA-Z]+)*\.[a-zA-Z]+(?:_[a-zA-Z]+)*)\}"
10+
1111
1212def snakify (s ):
13- return '_' .join (
14- re .sub ('([A-Z][a-z]+)' , r' \1' ,
15- re .sub (' ([A-Z]+)' , r' \1' ,
16- s . replace ( '-' , ' ' )) ).split ()
13+ return "_" .join (
14+ re .sub (
15+ "([A-Z][a-z]+)" , r" \1" , re .sub (" ([A-Z]+)" , r" \1" , s . replace ( "-" , " " ))
16+ ).split ()
1717 ).lower ()
1818
19+
1920def build_cube_name_look_up (cube_def ):
20- if ' cube_name_look_up' in cube_def :
21+ if " cube_name_look_up" in cube_def :
2122 return
2223 cube_name_look_up = {}
23- for cube_element in cube_def ['cubes' ]:
24- cube_name_look_up [cube_element ['name' ]] = cube_element
25- cube_def ['cube_name_look_up' ] = cube_name_look_up
24+ for cube_element in cube_def ["cubes" ]:
25+ cube_name_look_up [cube_element ["name" ]] = cube_element
26+ cube_def ["cube_name_look_up" ] = cube_name_look_up
27+
2628
2729def get_cube_from_cube_def (cube_def , cube_name ):
28- if ' cube_name_look_up' not in cube_def :
30+ if " cube_name_look_up" not in cube_def :
2931 build_cube_name_look_up (cube_def )
30- if cube_name in cube_def [' cube_name_look_up' ]:
31- return cube_def [' cube_name_look_up' ][cube_name ]
32+ if cube_name in cube_def [" cube_name_look_up" ]:
33+ return cube_def [" cube_name_look_up" ][cube_name ]
3234 return None
3335
36+
3437def get_cube_names_from_join_condition (join_condition ):
35- return [cube .split ('.' )[0 ] for cube in re .findall (snake_case , join_condition )]
38+ return [cube .split ("." )[0 ] for cube in re .findall (snake_case , join_condition )]
39+
3640
3741def traverse_graph (join_paths , cube_left , cube_right ):
3842 # Create a queue for BFS
3943 queue = []
4044 queue .append ([cube_left ])
4145
4246 while queue :
43- #Dequeue a vertex from queue
47+ # Dequeue a vertex from queue
4448 tmp_path = queue .pop (0 )
4549 # If this adjacent node is the destination node,
4650 # then return true
47- last_node = tmp_path [len (tmp_path )- 1 ]
51+ last_node = tmp_path [len (tmp_path ) - 1 ]
4852 if last_node == cube_right :
49- return '.' .join (tmp_path )
53+ return "." .join (tmp_path )
5054 # Else, continue to do BFS
5155 if last_node in join_paths :
5256 for cube in join_paths [last_node ]:
@@ -55,106 +59,128 @@ def traverse_graph(join_paths, cube_left, cube_right):
5559 new_path = tmp_path + [cube ]
5660 queue .append (new_path )
5761
58- typer .echo (f' Cubes are not reachable: { cube_left } , { cube_right } ' )
59- return '.' .join (cube_left , cube_right )
62+ typer .echo (f" Cubes are not reachable: { cube_left } , { cube_right } " )
63+ return "." .join (cube_left , cube_right )
6064
6165
6266def generate_cube_joins (cube_def , lookml_model ):
63- for explore in lookml_model ['explores' ]:
64- if 'joins' not in explore :
67+ if "explores" not in lookml_model or not lookml_model ["explores" ]:
68+ return cube_def
69+ for explore in lookml_model ["explores" ]:
70+ if "joins" not in explore :
6571 continue
6672
67- for join_element in explore [' joins' ]:
73+ for join_element in explore [" joins" ]:
6874 try :
69- cube_right = join_element ['name' ]
70-
71- joined_cubes = [cube for cube in get_cube_names_from_join_condition (join_element ['sql_on' ]) if cube != cube_right ]
75+ cube_right = join_element ["name" ]
76+
77+ joined_cubes = [
78+ cube
79+ for cube in get_cube_names_from_join_condition (
80+ join_element ["sql_on" ]
81+ )
82+ if cube != cube_right
83+ ]
7284 if joined_cubes :
73- if ' from' in join_element :
85+ if " from" in join_element :
7486 cube = {
75- ' name' : cube_right ,
76- ' extends' : join_element [' from' ],
77- ' shown' : False ,
87+ " name" : cube_right ,
88+ " extends" : join_element [" from" ],
89+ " shown" : False ,
7890 }
79- cube_def [' cubes' ].append (cube )
91+ cube_def [" cubes" ].append (cube )
8092 else :
8193 cube = get_cube_from_cube_def (cube_def , cube_right )
8294 if not cube :
83- typer .echo (f'Cube referenced in explores not found: { join_element ["name" ]} ' )
95+ typer .echo (
96+ f'Cube referenced in explores not found: { join_element ["name" ]} '
97+ )
8498 continue
8599
86- join_condition = join_element [' sql_on' ]
100+ join_condition = join_element [" sql_on" ]
87101
88- if ' joins' not in cube :
89- cube [' joins' ] = []
102+ if " joins" not in cube :
103+ cube [" joins" ] = []
90104
91- cube ['joins' ].append ({
92- 'name' : joined_cubes [0 ],
93- 'sql' : join_condition ,
94- 'relationship' : join_element ['relationship' ]
95- })
105+ cube ["joins" ].append (
106+ {
107+ "name" : joined_cubes [0 ],
108+ "sql" : join_condition ,
109+ "relationship" : join_element ["relationship" ],
110+ }
111+ )
96112 except Exception :
97- typer .echo (f' Error while parsing explore: { pformat (explore )} ' )
113+ typer .echo (f" Error while parsing explore: { pformat (explore )} " )
98114 typer .echo (traceback .format_exc ())
99115
100116 return cube_def
101117
118+
102119def generate_cube_views (cube_def , lookml_model ):
103- if 'views' not in cube_def :
104- cube_def ['views' ] = []
105- for explore in lookml_model ['explores' ]:
120+ if "views" not in cube_def :
121+ cube_def ["views" ] = []
122+ if "explores" not in lookml_model or not lookml_model ["explores" ]:
123+ return cube_def
124+ for explore in lookml_model ["explores" ]:
106125 try :
107- central_cube = explore ['name' ]
108- view_name = snakify (explore ['label' ])
126+ central_cube = explore ["name" ]
127+ label = explore .get ("label" , explore .get ("view_label" , explore ["name" ]))
128+ view_name = snakify (label )
109129 view = {
110- 'name' : view_name ,
111- 'description' : explore ['label' ],
112- 'cubes' : [{
113- 'join_path' : central_cube ,
114- 'includes' : "*" ,
115- 'alias' : view_name
116- }]
130+ "name" : view_name ,
131+ "description" : label ,
132+ "cubes" : [
133+ {"join_path" : central_cube , "includes" : "*" , "alias" : view_name }
134+ ],
117135 }
118136
119- if ' joins' not in explore :
120- cube_def [' views' ].append (view )
137+ if " joins" not in explore or not explore [ "joins" ] :
138+ cube_def [" views" ].append (view )
121139 continue
122140 # Create Graph
123141 join_paths = {}
124- for join_element in explore ['joins' ]:
125- cube_right = join_element ['name' ]
126- cube_left = [cube for cube in get_cube_names_from_join_condition (join_element ['sql_on' ]) if cube != cube_right ][0 ]
142+ for join_element in explore ["joins" ]:
143+ cube_right = join_element ["name" ]
144+ cube_left = [
145+ cube
146+ for cube in get_cube_names_from_join_condition (
147+ join_element ["sql_on" ]
148+ )
149+ if cube != cube_right
150+ ][0 ]
127151
128152 if cube_left in join_paths :
129153 join_paths [cube_left ].append (cube_right )
130154 else :
131155 join_paths [cube_left ] = [cube_right ]
132156 # traverse graph
133- for join_element in explore [' joins' ]:
134- cube_right = join_element [' name' ]
157+ for join_element in explore [" joins" ]:
158+ cube_right = join_element [" name" ]
135159 join_path = {
136- ' join_path' : traverse_graph (join_paths , central_cube , cube_right ),
137- ' includes' : "*" ,
138- ' alias' : cube_right
160+ " join_path" : traverse_graph (join_paths , central_cube , cube_right ),
161+ " includes" : "*" ,
162+ " alias" : cube_right ,
139163 }
140- view [' cubes' ].append (join_path )
141-
164+ view [" cubes" ].append (join_path )
165+
142166 # End
143- cube_def [' views' ].append (view )
167+ cube_def [" views" ].append (view )
144168
145169 except Exception :
146- typer .echo (f' Error while parsing explore: { pformat (explore )} ' )
170+ typer .echo (f" Error while parsing explore: { pformat (explore )} " )
147171 typer .echo (traceback .format_exc ())
148172 return cube_def
149173
150174
151175def parse_explores (lookml_model ):
152176 # First we read all possible lookml views.
153177 cube_def = parse_view (lookml_model , raise_when_views_not_present = False )
154- if 'explores' not in lookml_model :
155- raise Exception ('LookML explores are needed to generate Cube Views, no explore found in path.' )
178+ if "explores" not in lookml_model :
179+ raise Exception (
180+ "LookML explores are needed to generate Cube Views, no explore found in path."
181+ )
156182 cube_def = generate_cube_joins (cube_def , lookml_model )
157183
158184 cube_def = generate_cube_views (cube_def , lookml_model )
159185
160- return cube_def
186+ return cube_def
0 commit comments