-
Notifications
You must be signed in to change notification settings - Fork 15.8k
chore: abstract models and daos into superset-core #35259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review by Korbit AI
Korbit automatically attempts to detect when you fix issues in new commits.
Category | Issue | Status |
---|---|---|
Incomplete Abstract Interface Definition ▹ view | 🧠 Incorrect | |
Empty models module missing required exports ▹ view | 🧠 Not in standard | |
Missing batching guidance for bulk ID queries ▹ view | 🧠 Not in standard |
Files scanned
File Path | Reviewed |
---|---|
superset-core/src/superset_core/init.py | ✅ |
superset-core/src/superset_core/commands/init.py | ✅ |
superset-core/src/superset_core/dao/init.py | ✅ |
superset-core/src/superset_core/models/init.py | ✅ |
superset-core/src/superset_core/commands/types.py | ✅ |
superset-core/src/superset_core/models/base.py | ✅ |
superset/core/api/types/models.py | ✅ |
superset-core/src/superset_core/api/types/models.py | ✅ |
superset/commands/importers/v1/init.py | ✅ |
superset-core/src/superset_core/dao/types.py | ✅ |
superset/daos/base.py | ✅ |
superset/models/core.py | ✅ |
superset/connectors/sqla/models.py | ✅ |
Explore our documentation to understand the languages and file types we support and the files we ignore.
Check out our docs on how you can make Korbit work best for you and your team.
754388d
to
87b387a
Compare
|
||
# Class attributes that implementations should define | ||
model_cls: Optional[type[T_Model]] | ||
base_filter: Optional[BaseFilter] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use something more generic here instead of BaseFilter
, which is tightly coupled with FAB? Maybe we could rething how base filter works — it could be something passed to the instance, eg:
dao = DatasetDAO()
datasets = dao.find_by_ids([1, 2]) # equivalent to `skip_base_filter=True`
dao_for_user = dao.filtered(User.id == current_user.id)
datasets = dao_for_user.find_by_ids([1, 2]) # equivalent to `skip_base_filter=False`
In general I think the less dependencies superset-core
has, the better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fluent Interfaces are cool! but like that makes me think why not just use Query
from SQLAlchemy
?
Have a somewhat static base filter is a plus for security, we enforce that all DAO operations take into account a certain filter that enforces a security constraint
@abstractmethod | ||
def find_by_ids( | ||
self, | ||
model_ids: Union[list[str], list[int]], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use Collection
instead of list
? Here and in other places where order doesn't matter.
Also, can we use this opportunity to just use UUIDs everywhere, instead of having int IDs, string IDs, and UUIDs?
A tiny bit concerned about having
|
About Commands more specifically, I can see how some are useful here, but thinking most should either live in the app, or be treated as private. |
Note: another option I mentioned before would be to treat superset-core as 100% private, and have something like a |
@staticmethod | ||
@abstractmethod | ||
def get_datasets(query: BaseQuery | None = None, **kwargs: Any) -> list[Any]: | ||
def get_datasets(query: BaseQuery | None = None, **kwargs: Any) -> list[Dataset]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: We can use Query
from SQLAlchemy
@abstractmethod | ||
def find_by_id( | ||
self, model_id: Union[str, int], skip_base_filter: bool = False | ||
) -> Optional[T_Model]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: In the future we could have models with composite keys
__abstract__ = True | ||
|
||
|
||
class Database(CoreModel): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we call this AbstractDatabase
or BaseDatabase
?
@mistercrunch I share the same concerns as you and this is one of the motivations for exposing only the API definitions in
That's exactly what we defined in the SIP and the reason we publish the packages as 0.0.1-rcx in both NPM and PyPI. |
@mistercrunch I think we're achieving the same objective but through different means. The Correlating with your example, |
but clearly there are useful bits/methods/objects that we want to use/reuse within One example might be something like Python really lacking here, though doing it by convention with Also restating that I think there are many pieces of logic that logically belong in Two main approaches here:
|
@abstractmethod | ||
def find_by_id( | ||
self, model_id: Union[str, int], skip_base_filter: bool = False | ||
) -> Optional[T_Model]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding Optional[T_Model]
, consider: many ORMs provide get()
(raises) and get_or_none()
(returns None) to handle different use cases. Do we want/need both of these or are we good with what is here?
When debugging missing entities, would we rather see AttributeError: 'NoneType' object has no attribute 'name' on line 47
, or EntityNotFoundError: Dashboard with id=123 not found on line 23
?
SUMMARY
WIP
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
TESTING INSTRUCTIONS
ADDITIONAL INFORMATION