Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added dist/python_tabular-0.0.60-py3-none-any.whl
Binary file not shown.
Binary file added dist/python_tabular-0.0.60.tar.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "python_tabular"
version = "0.0.50"
version = "0.0.60"
authors = [
{ name="Curtis Stallings", email="curtisrstallings@gmail.com" },
]
Expand Down
20 changes: 13 additions & 7 deletions pytabular/__init__.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
import logging
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s :: %(module)s :: %(levelname)s :: %(message)s')
logging.debug('Logging configured...')
logger = logging.getLogger('PyTabular')
logger.setLevel(logging.DEBUG)
logger.debug('Logging configured...')
logger.debug(f'To update PyTabular logger...')
logger.debug(f'>>> import logging')
logger.debug(f'>>> pytabular.logger.setLevel(level=logging.INFO)')
logger.debug(f'Visit https://docs.python.org/3/library/logging.html#logging-levels for info...')

logging.debug(f'Setting up file paths for {__file__}')
logger.debug(f'Setting up file paths for {__file__}')
import os
import sys
dll = os.path.join(os.path.dirname(__file__),"dll")
sys.path.append(dll)
sys.path.append(os.path.dirname(__file__))

logging.debug(f'Beginning CLR references...')
logger.debug(f'Beginning CLR references...')
import clr
logging.debug('Adding Reference Microsoft.AnalysisServices.AdomdClient')
logger.debug('Adding Reference Microsoft.AnalysisServices.AdomdClient')
clr.AddReference('Microsoft.AnalysisServices.AdomdClient')
logging.debug('Adding Reference Microsoft.AnalysisServices.Tabular')
logger.debug('Adding Reference Microsoft.AnalysisServices.Tabular')
clr.AddReference('Microsoft.AnalysisServices.Tabular')
logging.debug('Adding Reference Microsoft.AnalysisServices')
logger.debug('Adding Reference Microsoft.AnalysisServices')
clr.AddReference('Microsoft.AnalysisServices')

logging.debug(f"Importing from the rest...")
logger.debug(f"Importing specifics in module...")
from . pytabular import Tabular
from . basic_checks import Return_Zero_Row_Tables, Table_Last_Refresh_Times, BPA_Violations_To_DF
from . logic_utils import pd_dataframe_to_m_expression, pandas_datatype_to_tabular_datatype
Expand Down
9 changes: 5 additions & 4 deletions pytabular/basic_checks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
logger = logging.getLogger('PyTabular')
from typing import List
import pytabular
from logic_utils import ticks_to_datetime
Expand All @@ -14,7 +15,7 @@ def Return_Zero_Row_Tables(model:pytabular.Tabular) -> List[str]:
Returns:
List[str]: List of table names where DAX COUNTROWS('Table Name') is nan or 0.
'''
logging.info(f'Executing Basic Function {sys._getframe(0).f_code.co_name}')
logger.info(f'Executing Basic Function {sys._getframe(0).f_code.co_name}')
query_function: str = 'COUNTROWS(_)'
df: pd.DataFrame = model.Query_Every_Table(query_function)
return df[df[f'[{query_function}]'].isna()]['[Table]'].to_list()
Expand All @@ -33,18 +34,18 @@ def Table_Last_Refresh_Times(model:pytabular.Tabular, group_partition:bool = Tru
pd.DataFrame: pd dataframe with the RefreshedTime property: https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.partition.refreshedtime?view=analysisservices-dotnet#microsoft-analysisservices-tabular-partition-refreshedtime
If group_partition == True and the table has multiple partitions, then df.groupby(by["tables"]).max()
'''
logging.info(f'Executing Basic Function {sys._getframe(0).f_code.co_name}')
logger.info(f'Executing Basic Function {sys._getframe(0).f_code.co_name}')
data = {\
"Tables":[partition.Table.Name for partition in model.Partitions],\
"Partitions":[partition.Name for partition in model.Partitions],\
"RefreshedTime":[ticks_to_datetime(partition.RefreshedTime.Ticks).strftime('%Y-%m-%dT%H:%M:%S.%fZ')[:-3] for partition in model.Partitions]\
}
df = pd.DataFrame(data)
if group_partition:
logging.debug('Grouping together to grain of Table')
logger.debug('Grouping together to grain of Table')
return df[["Tables","RefreshedTime"]].groupby(by=["Tables"]).max().reset_index(drop=False)
else:
logging.debug('Returning DF')
logger.debug('Returning DF')
return df

def BPA_Violations_To_DF(model:pytabular.Tabular,te2:str, bpa:str) -> pd.DataFrame:
Expand Down
7 changes: 4 additions & 3 deletions pytabular/best_practice_analyzer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
logger = logging.getLogger('PyTabular')
import requests as r
import atexit
import json
Expand All @@ -18,7 +19,7 @@ def Download_BPA_File(Download_Location:str = 'https://raw.githubusercontent.com
Returns:
str: File Path for the newly downloaded BPA.
'''
logging.info(f'Downloading BPA from {Download_Location}')
logger.info(f'Downloading BPA from {Download_Location}')
folder_location = os.path.join(os.getcwd(),Folder)
if os.path.exists(folder_location) == False:
os.makedirs(folder_location)
Expand All @@ -27,15 +28,15 @@ def Download_BPA_File(Download_Location:str = 'https://raw.githubusercontent.com
with open(file_location, 'w', encoding='utf-8') as bpa:
json.dump(response.json(), bpa, ensure_ascii=False, indent= 4)
if Auto_Remove:
logging.debug(f'Registering removal on termination... For {folder_location}')
logger.debug(f'Registering removal on termination... For {folder_location}')
atexit.register(remove_folder_and_contents, folder_location)
return file_location

class BPA:
'''Setting BPA Class for future work...
'''
def __init__(self, File_Path:str = 'Default') -> None:
logging.debug(f'Initializing BPA Class:: {File_Path}')
logger.debug(f'Initializing BPA Class:: {File_Path}')
if File_Path == 'Default':
self.Location: str = Download_BPA_File()
else:
Expand Down
9 changes: 5 additions & 4 deletions pytabular/logic_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
logger = logging.getLogger('PyTabular')
import datetime
import os
from typing import Dict, List
Expand Down Expand Up @@ -28,7 +29,7 @@ def pandas_datatype_to_tabular_datatype(df:pd.DataFrame)-> Dict:
Returns:
Dict: EX {'col1': <Microsoft.AnalysisServices.Tabular.DataType object at 0x0000023BFFBC9700>, 'col2': <Microsoft.AnalysisServices.Tabular.DataType object at 0x0000023BFFBC8840>, 'col3': <Microsoft.AnalysisServices.Tabular.DataType object at 0x0000023BFFBC9800>}
'''
logging.info(f'Getting DF Column Dtypes to Tabular Dtypes...')
logger.info(f'Getting DF Column Dtypes to Tabular Dtypes...')
tabular_datatype_mapping_key = {
'b':DataType.Boolean,
'i':DataType.Int64,
Expand Down Expand Up @@ -107,10 +108,10 @@ def m_list_expression_generator(list_of_strings:List[str]) -> str:
'''
string_components = ','.join([f'\"{string_value}\"' for string_value in list_of_strings])
return f'\u007b{string_components}\u007d'
logging.debug(f'Executing m_list_generator()... for {df.columns}')
logger.debug(f'Executing m_list_generator()... for {df.columns}')
columns = m_list_expression_generator(df.columns)
expression_str = f"let\nSource=#table({columns},\n"
logging.debug(f'Iterating through rows to build expression... df has {len(df)} rows...')
logger.debug(f'Iterating through rows to build expression... df has {len(df)} rows...')
expression_list_rows = []
for index, row in df.iterrows():
expression_list_rows += [m_list_expression_generator(row.to_list())]
Expand All @@ -125,5 +126,5 @@ def remove_folder_and_contents(folder_location):
'''
import shutil
if os.path.exists(folder_location):
logging.info(f'Removing Dir and Contents -> {folder_location}')
logger.info(f'Removing Dir and Contents -> {folder_location}')
shutil.rmtree(folder_location)
Loading