Skip to content
This repository was archived by the owner on Mar 31, 2026. It is now read-only.

Commit 3af06d2

Browse files
authored
refactor: use Factory pattern for GenericTable (#36)
1 parent 3c5f50b commit 3af06d2

1 file changed

Lines changed: 76 additions & 70 deletions

File tree

dataform2looker/database_mappers.py

Lines changed: 76 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -80,76 +80,6 @@ def __init__(
8080
self.column_dictionary["timeframes"] = self.time_frames
8181

8282

83-
class GenericTable:
84-
"""Base Table class for representing tables from different database types.
85-
86-
Attributes:
87-
table_id (str): The full ID of the table in the database.
88-
table_name (str): The name of the table (extracted from `table_id`).
89-
dimensions (list[dict]): A list of dictionaries representing dimensions in the table.
90-
dimension_group (list[dict]): A list of dictionaries representing time dimension groups.
91-
92-
Methods:
93-
__init__(self, table_id: str, db_type: str) -> None:
94-
Initializes the `GenericTable` object based on the `db_type`.
95-
Currently supports only "bigquery" and raises an exception for other types.
96-
97-
Raises:
98-
UnsupportedDatabaseTypeError: If an unsupported `db_type` is provided.
99-
""" # noqa: E501
100-
101-
def __init__(self, table_id: str, db_type: str = "bigquery") -> None:
102-
"""Initializes the `GenericTable` object based on the database type.
103-
104-
Args:
105-
table_id: The full ID of the table in the database.
106-
db_type: The type of the database ("bigquery" currently supported).
107-
108-
Raises:
109-
UnsupportedDatabaseTypeError: If an unsupported `db_type` is provided.
110-
""" # noqa: E501
111-
if db_type != "bigquery":
112-
raise UnsupportedDatabaseTypeError(db_type)
113-
self.__table = BigQueryTable(table_id)
114-
self.table_id = table_id
115-
self.table_name = self.__table.table_name
116-
self.__db_type = db_type
117-
# TODO implement self.description = self.__table.description
118-
# This is not implemented at the moment lkml views don't support descriptions
119-
# At the moment the dictionary for views and dimensions are built
120-
# this is because the lkml lib requires the dict
121-
# in case something different is used then we would need to
122-
# re-factor the dictionary for GenericTable and Column
123-
self.dimensions = [
124-
column.column_dictionary
125-
for column in self.__table.columns
126-
if column.dimension_type == "dimension"
127-
]
128-
logging.debug(f"Dimensions for table {self.table_name}: {self.dimensions}")
129-
self.dimension_group = [
130-
column.column_dictionary
131-
for column in self.__table.columns
132-
if column.dimension_type == "time_dimension_group"
133-
]
134-
logging.debug(
135-
f"Dimensions Group for table {self.table_name}: {self.dimension_group}"
136-
)
137-
self.measures = [{"type": "count", "name": "count"}]
138-
# TODO it should be possible to include other measures by passing an argument
139-
# Include measures if needed such as sums of all number dimensions
140-
# include count_distinct
141-
142-
self.table_dictionary = {
143-
"view": {
144-
"name": f"{self.table_name}",
145-
"sql_table_name": f"{table_id}",
146-
"dimensions": self.dimensions,
147-
"dimension_groups": self.dimension_group,
148-
"measures": self.measures,
149-
}
150-
}
151-
152-
15383
class BigQueryTable:
15484
"""Base Table class for representing BigQuery tables and their column information.
15585
@@ -257,3 +187,79 @@ def __get_columns(self) -> list[Column]:
257187
for field in table.schema
258188
]
259189
return columns
190+
191+
192+
class GenericTable:
193+
"""Base Table class for representing tables from different database types.
194+
195+
Attributes:
196+
table_id (str): The full ID of the table in the database.
197+
table_name (str): The name of the table (extracted from `table_id`).
198+
dimensions (list[dict]): A list of dictionaries representing dimensions in the table.
199+
dimension_group (list[dict]): A list of dictionaries representing time dimension groups.
200+
201+
Methods:
202+
__init__(self, table_id: str, db_type: str) -> None:
203+
Initializes the `GenericTable` object based on the `db_type`.
204+
Uses a factory pattern to dynamically load the correct mapper.
205+
206+
Raises:
207+
UnsupportedDatabaseTypeError: If an unsupported `db_type` is provided.
208+
""" # noqa: E501
209+
210+
_MAPPERS = {
211+
"bigquery": BigQueryTable,
212+
}
213+
214+
def __init__(self, table_id: str, db_type: str = "bigquery") -> None:
215+
"""Initializes the `GenericTable` object based on the database type.
216+
217+
Args:
218+
table_id: The full ID of the table in the database.
219+
db_type: The type of the database ("bigquery" currently supported).
220+
221+
Raises:
222+
UnsupportedDatabaseTypeError: If an unsupported `db_type` is provided.
223+
""" # noqa: E501
224+
mapper_class = self._MAPPERS.get(db_type)
225+
if not mapper_class:
226+
raise UnsupportedDatabaseTypeError(db_type)
227+
228+
self.__table = mapper_class(table_id)
229+
self.table_id = table_id
230+
self.table_name = self.__table.table_name
231+
self.__db_type = db_type
232+
# TODO implement self.description = self.__table.description
233+
# This is not implemented at the moment lkml views don't support descriptions
234+
# At the moment the dictionary for views and dimensions are built
235+
# this is because the lkml lib requires the dict
236+
# in case something different is used then we would need to
237+
# re-factor the dictionary for GenericTable and Column
238+
self.dimensions = [
239+
column.column_dictionary
240+
for column in self.__table.columns
241+
if column.dimension_type == "dimension"
242+
]
243+
logging.debug(f"Dimensions for table {self.table_name}: {self.dimensions}")
244+
self.dimension_group = [
245+
column.column_dictionary
246+
for column in self.__table.columns
247+
if column.dimension_type == "time_dimension_group"
248+
]
249+
logging.debug(
250+
f"Dimensions Group for table {self.table_name}: {self.dimension_group}"
251+
)
252+
self.measures = [{"type": "count", "name": "count"}]
253+
# TODO it should be possible to include other measures by passing an argument
254+
# Include measures if needed such as sums of all number dimensions
255+
# include count_distinct
256+
257+
self.table_dictionary = {
258+
"view": {
259+
"name": f"{self.table_name}",
260+
"sql_table_name": f"{table_id}",
261+
"dimensions": self.dimensions,
262+
"dimension_groups": self.dimension_group,
263+
"measures": self.measures,
264+
}
265+
}

0 commit comments

Comments
 (0)