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
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,5 +244,20 @@ model.Query(query_str, Effective_User = user_email)
#So you won't have to reconnect on every query
```

#### Refresh Related Tables
Ever need to refresh related tables of a Fact? Now should be a lot easier.
```python
import pytabular as p

#Connect to model
model = p.Tabular(CONNECTION_STR)

#Get related tables
tables = model.Tables[TABLE_NAME].Related()

#Now just refresh like usual...
tables.Refresh()
```

### Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md)
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.2.2"
version = "0.2.3"
authors = [
{ name="Curtis Stallings", email="curtisrstallings@gmail.com" },
]
Expand Down
7 changes: 5 additions & 2 deletions pytabular/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ def __getattr__(self, attr):
class PyObjects:
def __init__(self, objects) -> None:
self._objects = objects
self._display = Table(title="PyObject Collection")
for index, obj in enumerate(self._objects):
self._display.add_row(str(index), obj.Name)

def __repr__(self) -> str:
return f"{len(self._objects)}"
def __rich_repr__(self) -> str:
Console().print(self._display)

def __getitem__(self, object):
if isinstance(object, str):
Expand Down
7 changes: 7 additions & 0 deletions pytabular/pytabular.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from partition import PyPartitions
from column import PyColumns
from measure import PyMeasures
from relationship import PyRelationship, PyRelationships
from object import PyObject
from refresh import PyRefresh
from query import Connection
Expand Down Expand Up @@ -115,6 +116,12 @@ def Reload_Model_Info(self) -> bool:
self.Tables = PyTables(
[PyTable(table, self) for table in self.Model.Tables.GetEnumerator()]
)
self.Relationships = PyRelationships(
[
PyRelationship(relationship, self)
for relationship in self.Model.Relationships.GetEnumerator()
]
)
self.Partitions = PyPartitions(
[partition for table in self.Tables for partition in table.Partitions]
)
Expand Down
4 changes: 3 additions & 1 deletion pytabular/refresh.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import pandas as pd
from logic_utils import ticks_to_datetime
from typing import Union, Dict, Any
from table import PyTable
from table import PyTable, PyTables
from partition import PyPartition
from abc import ABC

Expand Down Expand Up @@ -275,6 +275,8 @@ def _request_refresh(self, object):
logger.debug(f"Requesting Refresh for {object}")
if isinstance(object, str):
self._refresh_table(self._find_table(object))
elif isinstance(object, PyTables):
[self._refresh_table(table) for table in object]
elif isinstance(object, Dict):
self._refresh_dict(object)
elif isinstance(object, PyTable):
Expand Down
73 changes: 73 additions & 0 deletions pytabular/relationship.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import logging
from object import PyObject
from pytabular.object import PyObjects
from pytabular.table import PyTable, PyTables

from Microsoft.AnalysisServices.Tabular import (
CrossFilteringBehavior,
SecurityFilteringBehavior,
)

from typing import Union

logger = logging.getLogger("PyTabular")


class PyRelationship(PyObject):
"""Wrapper for [Microsoft.AnalysisServices.Tabular.Table](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.table?view=analysisservices-dotnet).
With a few other bells and whistles added to it. You can use the table to access the nested Columns and Partitions. WIP

Attributes:
Model: Reference to Tabular class
Partitions: Reference to Table Partitions
Columns: Reference to Table Columns
"""

def __init__(self, object, model) -> None:
super().__init__(object)
self.Model = model
self.CrossFilteringBehavior = CrossFilteringBehavior(
self.CrossFilteringBehavior.value__
).ToString()
self.SecurityFilteringBehavior = SecurityFilteringBehavior(
self.SecurityFilteringBehavior.value__
).ToString()
self.To_Table = self.Model.Tables[self.ToTable.Name]
self.To_Column = self.To_Table.Columns[self.ToColumn.Name]
self.From_Table = self.Model.Tables[self.FromTable.Name]
self.From_Column = self.From_Table.Columns[self.FromColumn.Name]
self._display.add_row("Is Active", str(self.IsActive))
self._display.add_row("Cross Filtering Behavior", self.CrossFilteringBehavior)
self._display.add_row(
"Security Filtering Behavior", self.SecurityFilteringBehavior
)
self._display.add_row(
"From", f"'{self.From_Table.Name}'[{self.From_Column.Name}]"
)
self._display.add_row("To", f"'{self.To_Table.Name}'[{self.To_Column.Name}]")


class PyRelationships(PyObjects):
"""Iterator to handle tables. Accessible via `Tables` attribute in Tabular class.

Args:
PyTable: PyTable class
"""

def __init__(self, objects) -> None:
super().__init__(objects)

def Related(self, object: Union[PyTable, str]):
table_to_find = object if isinstance(object, str) else object.Name
to_tables = [
rel.To_Table
for rel in self._objects
if rel.From_Table.Name == table_to_find
]
from_tables = [
rel.From_Table
for rel in self._objects
if rel.To_Table.Name == table_to_find
]
to_tables += from_tables
return PyTables(to_tables)
7 changes: 7 additions & 0 deletions pytabular/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ def Refresh(self, *args, **kwargs) -> pd.DataFrame:
"""
return self.Model.Refresh(self, *args, **kwargs)

def Related(self):
return self.Model.Relationships.Related(self)


class PyTables(PyObjects):
"""Iterator to handle tables. Accessible via `Tables` attribute in Tabular class.
Expand All @@ -81,3 +84,7 @@ class PyTables(PyObjects):

def __init__(self, objects) -> None:
super().__init__(objects)

def Refresh(self, *args, **kwargs):
model = self._objects[0].Model
return model.Refresh(self, *args, **kwargs)