fix: update pk field only raises unfriendly error#1873
fix: update pk field only raises unfriendly error#1873waketzheng merged 8 commits intotortoise:developfrom
Conversation
CodSpeed Performance ReportMerging #1873 will not alter performanceComparing Summary
|
Pull Request Test Coverage Report for Build 13321805682Details
💛 - Coveralls |
|
@waketzheng I added benchmarks for updates, let's merge them first so we have a baseline for performance and can be sure that this changes doesn't impact it significantly. |
henadzit
left a comment
There was a problem hiding this comment.
Can you please rebase on top of the latest changes in develop?
| @@ -267,13 +267,15 @@ async def execute_update( | |||
| values = [] | |||
| expressions = {} | |||
| for field in update_fields or self.model._meta.fields_db_projection.keys(): | |||
There was a problem hiding this comment.
The current logic assumes that if no values and no expressions, then the user must have been passed pk as part of update_fields. That is a bit hard to follow. What do you think about the version below?
for field in update_fields or self.model._meta.fields_db_projection.keys():
field_obj = self.model._meta.fields_map[field]
if field_obj.pk:
if update_fields:
raise OperationalError(
f"Can't update pk field, use `{self.model.__name__}.create` instead."
)
continueThere was a problem hiding this comment.
I think we should allow .update_fields=['id', 'xxx'] as the Django do. And show warning to make sure user want to do that.
There was a problem hiding this comment.
I think we should allow .update_fields=['id', 'xxx'] as the Django do. And show warning to make sure user want to do that.
Why introduce a behavior that triggers a warning? This doesn't seem like a good design. You usually introduce warnings about deprecation or something you want users to stop doing.
| @@ -267,13 +267,15 @@ async def execute_update( | |||
| values = [] | |||
| expressions = {} | |||
| for field in update_fields or self.model._meta.fields_db_projection.keys(): | |||
There was a problem hiding this comment.
I think we should allow .update_fields=['id', 'xxx'] as the Django do. And show warning to make sure user want to do that.
Why introduce a behavior that triggers a warning? This doesn't seem like a good design. You usually introduce warnings about deprecation or something you want users to stop doing.
tortoise/backends/base/executor.py
Outdated
| RuntimeWarning, | ||
| ) | ||
| continue | ||
| if isinstance(instance_field := getattr(instance, field), Expression): |
There was a problem hiding this comment.
This is quite hard to read. I can see why you would want to use the := operator in a simple if-else like
if a := something:
...
but in this case the assignment is hidden within a function call which make it quite hard to read. I would rather have the variable outside of the if check.
There was a problem hiding this comment.
Updated.
Look at this: https://peps.python.org/pep-0572/#examples
To keep easy to read:
- This is ok:
match1 = pattern1.match(data)
if match1:
print(match1)
# Change to be
if match1 := pattern1.match(data):
print(match1)- This ok too
group = re.match(data).group(1) if re.match(data) else None
# Change to be
group = m.group(1) if (m := re.match(data)) else NoneThis is not recommended:
if (match1 := pattern1.match(data)) and len(match1.groups()) > 2:
print(match1)This not recommended either:
if isinstance(m := get_object(), str):
return m|
@henadzit All done.
But I don't quite get the point that why do you say |
Description
Close #1870
Motivation and Context
Explicit raises OptionalError when executing
await model.save(update_fields=['id'])How Has This Been Tested?
make ci
Checklist: