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
Resolved #30032 -- Added support for query expressions as default values #11783
Conversation
7d4c13e
to
8f10982
Compare
42ac767
to
549091b
Compare
ad4a5a6
to
2186597
Compare
@felixxm I updated the release note to include mention Oracle support for database default. I believe this concludes issue 29444. It's been plenty fun :) Let me know if you have any change requests. |
e4cae51
to
ec2ed9a
Compare
ec2ed9a
to
a6037b1
Compare
Ref #11568 |
a6037b1
to
acb09c8
Compare
@apollo13, @charettes maybe you would be interested in reviewing this too, since you have been very involved with the |
what about migrations? |
Can you elaborate a bit more what you mean? This is a rather small change, I am happy to put in more effort to move this over the finish line. |
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'd like to see more tests around invalid expression such as ones that span joins, aggregation, window functions. I think we'll want to add checks for that.
Also primary key interactions should be tested (e.g. (primary_key=True , default=Func('uuid'))
) and the documentation should make it clear that this is not a db_default
option that results in using the SQL DEFAULT expr
at the table definition level. We already get report of users surprised Django doesn't use DEFAULT
when only Python callable are supported and I feel this blurs the line even more.
Actually, most of them would work. However, since we do not allow
Besides it being borderline impossible to implement a comprehensive check, without refactoring all expressions, I don't even know if it's wise to add a one. See strictly speaking any value is allowed and most that don't work should. However, if they don't you will get an error. Analog to that, you can provide a callable, that returns a completely different type than the field at hand. We don't have a check for that, and that might be a good thing. I don't know I am torn about this. I am happy to add tests tho. But I might need a bit more input before I can progress.
I added a note about the behavior. There already is a test for a primary key, I didn't use UUID, since this the functions are different across Oracle and Postgres and in the latter the |
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.
A scattering of thoughts on what is currently implemented. Maybe some more complex tests using some math functions and operators, and ExpressionWrapper
could be added?
6bef39c
to
afb26cf
Compare
4f223f0
to
1026337
Compare
@auvipy you seem very excited, would you care to review the patch to move things along a little quicker? This is a rather complex patch, so every pair eye helps. |
@InvalidInterrupt thanks for the thorough review, it really helped to get this forward. If you are happy with my changes let me know and I will squash my changes to get this ready for check in. |
27a3a0d
to
914e420
Compare
b7ef401
to
dac5fe2
Compare
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
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.
A couple comments.
@@ -121,6 +121,15 @@ def __exit__(self, exc_type, exc_value, traceback): | |||
|
|||
# Core utility functions | |||
|
|||
def prepare_param(self, node): | |||
sql, params = None, (node,) |
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 assignment and tuple creation / unpacking, etc. isn't used in the case that hasattr
is true. I also noted this below, but the conversation is marked resolved.
@@ -132,17 +141,25 @@ def execute(self, sql, params=()): | |||
) | |||
# Account for non-string statement objects. | |||
sql = str(sql) | |||
prepared_params = None | |||
if params is not 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.
Can this be if params
? Does the if
block need to execute if params
is an empty tuple (the method default)?
@codingjoe Thanks for all your efforts 🥇 and sorry for the late reply 💔 . Unfortunately, we need to make few things to make it reviewable again:
I hope it makes sense. |
@felixxm I know the drill 😉 |
I can promise a detailed review before Django 4.1 feature freeze, if it will be reviewable again. |
Hey @codingjoe, while reading all the commentary for ticket-32577, I was pointed at this PR. Do you have time to keep working on this PR? I could help with the rebasing and restyling if you don't have the time. Let me know! |
@codingjoe I have rebased and fixed conflicts and code style. There were a couple of changes I wasn't sure about so you'd need to review and fix accordingly:
Hopefully you can pick up this PR from here! Let us know. Thanks! |
I also had to revert this change because lots of tests (specifically in diff --git a/django/db/models/base.py b/django/db/models/base.py
index 0f8af9f9204e3..11b7f04dd34ef 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -872,7 +872,7 @@ def _save_table(self, raw=False, cls=None, force_insert=False,
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
if results:
for value, field in zip(results[0], returning_fields):
- setattr(self, field.attname, value)
+ setattr(self, field.attname, field.to_python(value))
return updated
def _do_update(self, base_qs, using, pk_val, values, update_fields, forced_update): |
Closing due to inactivity. |
I'll try to get to it this Xmas 🎄 |
ticket-30032
TL;DR
Adds support for query expression as default values for PostgreSQL and Oracle. The expression are not stored on the database as defaults but are passed on
INSERT
andUPDATE
.