Skip to content
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

fix: models get_or_create keyerror #1584

Merged
merged 19 commits into from
Jun 16, 2024
Merged

Conversation

jiangying000
Copy link
Contributor

@abondar
Copy link
Member

abondar commented Apr 25, 2024

Could you please rebase your PR on actual develop branch?
Also please add small test on it and info about change to changelog

@jiangying000
Copy link
Contributor Author

Could you please rebase your PR on actual develop branch? Also please add small test on it and info about change to changelog

yes, i did this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. kwargs is 'Query parameters', defaults is 'Default values used to update the object', when they have same key with different values, value of kwargs should be covered by defaults. That is to say code must be: merged_defaults = {**kwargs, **defaults}
  2. merged_defaults = ... should be in front of try: (just put it after line 1082)
  3. return ... shoud be stay as one line, do not make it into three lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though that is how it works in django - for me it seems strange that default value overrides explicit value

I would expect opposite behaviour of this

I dunno if we should proceed with this change, as leaving merging on user side seems like more transparent behaviour

Copy link
Contributor Author

@jiangying000 jiangying000 May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would also expect explicit kv overrides the default

do merge rather than throw err seems better for me

when i write:

    mdl.id = 135
    await self.cls.update_or_create(id=mdl.id, defaults=dict(mdl))

i was expecting row with id 135 being updated or created

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me - in your case you should do explicit get_or_create without defaults and them make usual update() for returned object
That shouldn't affect performance, as it is basically what we already do

Django also, from 5.0, introduced separate create_defaults param for update_to_create for similar cases to make them less confusing
May be we should look into doing it too, but it seems there could be some issues in tortoise to use select_for_update with get_or_create

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though that is how it works in django - for me it seems strange that default value overrides explicit value

I would expect opposite behaviour of this

I dunno if we should proceed with this change, as leaving merging on user side seems like more transparent behaviour

Our team use tortoise-orm for a long time, and we are proficient in django. So we prefer it have the same result with django.

Or maybe an exception can be raised when kwargs and defaults have same key with different values:

for key in (defaults.keys() & kwargs.keys()):
    if (default_value := defaults[key]) != (query_value := kwargs[key]):
        raise tortoise.exceptions.ParamError(f'Conflict value with {key=}: {default_value=}  vs {query_value=}')

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe an exception can be raised when kwargs and defaults have same key with different values:

I would prefer that, as django behaviour seems confusing to me here, but doing solution opposite to them - would be also confusing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe an exception can be raised when kwargs and defaults have same key with different values:

I would prefer that, as django behaviour seems confusing to me here, but doing solution opposite to them - would be also confusing

ok, updated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the diff from github is wrong

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should add case about kwargs and defaults have same key and same value

@@ -23,6 +23,7 @@
from pypika.terms import Term
from typing_extensions import Self

import tortoise
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this line

except DoesNotExist:
for key in (defaults.keys() & kwargs.keys()):
if (default_value := defaults[key]) != (query_value := kwargs[key]):
raise tortoise.exceptions.ParamsError(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change it to:

raise ParamsError("...")

Then run make style to reformat this file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

@waketzheng
Copy link
Contributor

@jiangying000 How is that?

@jiangying000
Copy link
Contributor Author

@jiangying000 How is that?

sorry, no progress yet, too busy dealing with my employment job tasks

@jiangying000
Copy link
Contributor Author

feel free to take on this pr, or close it

@waketzheng
Copy link
Contributor

feel free to take on this pr, or close it

I have make a pr, could you merge it into your develop branch?
jiangying000#1

refactor: optimize update_or_create logic
@jiangying000
Copy link
Contributor Author

feel free to take on this pr, or close it

I have make a pr, could you merge it into your develop branch? jiangying000#1

done, thanks

@waketzheng
Copy link
Contributor

@abondar Could you review this?

@abondar
Copy link
Member

abondar commented Jun 12, 2024

@waketzheng seems like there is some issue
tests hangs up somewhere on ODBC tests

Also we would need to update changelog to put change in new section

@waketzheng
Copy link
Contributor

@waketzheng seems like there is some issue tests hangs up somewhere on ODBC tests

Also we would need to update changelog to put change in new section

@abondar done

@coveralls
Copy link

coveralls commented Jun 14, 2024

Pull Request Test Coverage Report for Build 9501103456

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 13 of 16 (81.25%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.07%) to 89.021%

Changes Missing Coverage Covered Lines Changed/Added Lines %
tortoise/models.py 13 16 81.25%
Totals Coverage Status
Change from base Build 9479020180: 0.07%
Covered Lines: 5868
Relevant Lines: 6494

💛 - Coveralls

@waketzheng
Copy link
Contributor

@abondar Cloud you review it?

@abondar abondar merged commit 6b01815 into tortoise:develop Jun 16, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants