-
-
Notifications
You must be signed in to change notification settings - Fork 399
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
Changes from 8 commits
eac9e73
95f2547
6e1e1f9
44f7b43
d36cfc5
d6d6dfc
57958df
33db833
b2ec794
ea7b404
665a36c
8ac9ddf
173411e
038b475
260bd9d
9562b43
feb9b9a
a8dab73
8725fa4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks, done There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
i was expecting row with id 135 being updated or created There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems to me - in your case you should do explicit Django also, from 5.0, introduced separate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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=}') There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I would prefer that, as django behaviour seems confusing to me here, but doing solution opposite to them - would be also confusing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
ok, updated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the diff from github is wrong There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ | |
from pypika.terms import Term | ||
from typing_extensions import Self | ||
|
||
import tortoise | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this line |
||
from tortoise import connections | ||
from tortoise.backends.base.client import BaseDBAsyncClient | ||
from tortoise.exceptions import ( | ||
|
@@ -1067,6 +1068,7 @@ async def get_or_create( | |
:param using_db: Specific DB connection to use instead of default bound | ||
:param kwargs: Query parameters. | ||
:raises IntegrityError: If create failed | ||
:raises TransactionManagementError: If transaction error | ||
""" | ||
if not defaults: | ||
defaults = {} | ||
|
@@ -1075,8 +1077,13 @@ async def get_or_create( | |
return await cls.filter(**kwargs).using_db(db).get(), False | ||
except DoesNotExist: | ||
try: | ||
for key in (defaults.keys() & kwargs.keys()): | ||
if (default_value := defaults[key]) != (query_value := kwargs[key]): | ||
raise tortoise.exceptions.ParamsError( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change it to: raise ParamsError("...") Then run |
||
f'Conflict value with {key=}: {default_value=} vs {query_value=}') | ||
async with in_transaction(connection_name=db.connection_name) as connection: | ||
return await cls.create(using_db=connection, **defaults, **kwargs), True | ||
merged_defaults = {**kwargs, **defaults} | ||
return await cls.create(using_db=connection, **merged_defaults), True | ||
except IntegrityError as exc: | ||
try: | ||
return await cls.filter(**kwargs).using_db(db).get(), False | ||
|
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 add case about
kwargs
anddefaults
have same key and same value