-
Notifications
You must be signed in to change notification settings - Fork 14k
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
chore(dao): Replace save/overwrite with create/update respectively #24467
chore(dao): Replace save/overwrite with create/update respectively #24467
Conversation
8d1fa15
to
b399955
Compare
b399955
to
6d67571
Compare
Codecov Report
@@ Coverage Diff @@
## master #24467 +/- ##
==========================================
- Coverage 68.97% 68.96% -0.01%
==========================================
Files 1901 1901
Lines 74008 73964 -44
Branches 8183 8183
==========================================
- Hits 51047 51010 -37
+ Misses 20840 20833 -7
Partials 2121 2121
Flags with carried forward coverage won't be shown. Click here to find out more.
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
c4b0f1b
to
84394ec
Compare
:raises: DAOCreateFailedError | ||
def create( | ||
cls, | ||
item: T | None = None, |
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.
To accommodate the save
functionality I extended the create
method to accept a predefined object.
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.
Would be possible to set item
as T | dict[str, Any] | None
and remove the attributes
parameter?
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.
@michael-s-molina that's an interesting idea, though I wonder if we're overloading item
here. I was likely just trying to replicate the same behavior (familiarity) as the update
method which needs to have either/or both the item and attributes—well technically you're just updating an existing item, but it seems cleaner (from a DRY perspective) to have the base update
method perform said logic.
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.
Technically I can call create
with both item
and attributes
set as None
. It feels really weird for me.
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.
@michael-s-molina sorry for the delay in getting back to you on this. You mention you could do something of the form,
chart = ChartDAO.create()
which would try to create a new chart and persist it to the database. This operation would succeed if the model attributes can be nullable. I realize this isn't a typical workflow, but I'm not entirely sure it's wrong per se.
BTW I totally agree there's room for improvement here—I was even toiling with the idea that maybe create
and update
should be handled by a single upsert
method—however I do sense this PR helps ensure that the code is more consistent, i.e., the save
and override
methods have been removed and both the create
and update
methods have the same function signature.
""" | ||
Generic update a model | ||
:raises: DAOCreateFailedError |
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.
Previously this comment was wrong.
def update(cls, model: T, properties: dict[str, Any], commit: bool = True) -> T: | ||
def update( | ||
cls, | ||
item: T | None = None, |
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.
The item and/or attributes are now optional which provides more flexibility.
superset/daos/base.py
Outdated
@@ -38,12 +39,12 @@ class BaseDAO(Generic[T]): | |||
Base DAO, implement base CRUD sqlalchemy operations | |||
""" | |||
|
|||
model_cls: Optional[type[Model]] = None | |||
model_cls: type[Model] | None = None |
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.
This was automatically updated via pyupgrade
.
ee8d86d
to
0b8c785
Compare
66cdeed
to
dd656b1
Compare
def create( | ||
cls, | ||
item: T | None = None, | ||
attributes: dict[str, Any] | None = None, |
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.
I used the term "attributes" rather than "properties" as this is the lingo that SQLAlchemy uses—combined with the fact you use the setattr
method for setting them.
@michael-s-molina I've hopefully addressed/answered your questions? Would it be possible to (re)review the change? Once merged I was hoping to make some inroads in terms of how we commit/rollback changes as well as grouping all the commands together. Ideally these tasks will be easier to manage after once this PR is merged otherwise the merge conflict could be rather convoluted. |
3b06454
to
610edf5
Compare
610edf5
to
6110e6b
Compare
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.
LGTM
SUMMARY
Per SIP-92 Proposal for restructuring the Python code base #24331 organized all the DAOs to be housed within a shared folder—the result of which highlighted numerous inconsistencies, repetition, and inefficiencies.
This PR (one of many smaller bitesized PRs) replaces the
save
andoverwrite
methods withcreate
andupdate
methods respectively which removes a bunch of copypasta.Note this PR required a fair amount of yak shaving as the
create
andupdate
methods needed to be updated to support a combination of a instance and/or the attributes representing the instance.Future fast follows intend to:
create
andupdate
into anupsert
method.BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
TESTING INSTRUCTIONS
CI.
ADDITIONAL INFORMATION