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

Fixed #31300 -- Added GeneratedField model field. #16860

Merged
merged 1 commit into from Sep 7, 2023

Conversation

LilyFoote
Copy link
Contributor

Builds on top of #16417.

@LilyFoote
Copy link
Contributor Author

@jpnauta Here's the first draft of Oracle support.

django/db/backends/base/features.py Outdated Show resolved Hide resolved
django/db/models/fields/generated.py Show resolved Hide resolved
django/db/models/fields/generated.py Outdated Show resolved Hide resolved
django/db/models/fields/generated.py Outdated Show resolved Hide resolved
tests/migrations/test_operations.py Outdated Show resolved Hide resolved
tests/model_fields/models.py Outdated Show resolved Hide resolved
tests/model_fields/models.py Outdated Show resolved Hide resolved
@LilyFoote
Copy link
Contributor Author

I'm not sure why the jenkins builds aren't running properly. @felixxm any ideas?

@sarahboyce
Copy link
Contributor

I'm not sure why the jenkins builds aren't running properly. @felixxm any ideas?

This might have coincided with the degraded performance/incident of GitHub actions on the 16th May (see here). Push up a small change (can reword a commit) and see if this fixes it? I can't see this PR in the list of stuff picked up by jenkins

@Lancelot03
Copy link

I'm new here. I think by pushing a small change and monitoring Jenkins, you can assess if the issue persists or if the new commit triggers the build successfully. This can help determine if the previous problem was due to the degraded performance of GitHub Actions or if there might be other underlying issues with Jenkins configuration or integration.
This might can help.

@LilyFoote
Copy link
Contributor Author

That doesn't appear to have fixed things.

@sarahboyce
Copy link
Contributor

Found an error log: https://djangoci.com/view/PR%20Builders/job/pr-mariadb/lastFailedBuild/console
(don't understand what is needed to be done 🤔)

@felixxm
Copy link
Member

felixxm commented May 26, 2023

I'd start by fixing conflicts and rebasing from the main branch.

@LilyFoote
Copy link
Contributor Author

I'd start by fixing conflicts and rebasing from the main branch.

I was hoping to avoid that because I didn't want to rebase @jpnauta's commits so this PR could cleanly land back on his.

@LilyFoote
Copy link
Contributor Author

@felixxm At DjangoCon Europe sprints we discussed the Oracle error we're getting here and I think we settled on updating the Jenkins install to set MAX_STRING_SIZE=EXTENDED. Do I need to open a ticket somewhere for that or is leaving this comment enough?

@LilyFoote LilyFoote changed the title Add Oracle support for generated fields. Refs #31300 -- Add support for function-based virtual fields on Oracle Jul 27, 2023
@LilyFoote
Copy link
Contributor Author

@felixxm I've removed the extra feature flag. The main blocker I think is #16860 (comment), followed by fixing the merge conflicts.

Copy link
Member

@felixxm felixxm left a comment

Choose a reason for hiding this comment

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

@felixxm I've removed the extra feature flag. The main blocker I think is #16860 (comment), followed by fixing the merge conflicts.

Tests should pass when a database doesn't support collations. I've added comments with required feature flags checks.

django/db/backends/sqlite3/features.py Show resolved Hide resolved
tests/model_fields/models.py Outdated Show resolved Hide resolved
tests/model_fields/test_generatedfield.py Outdated Show resolved Hide resolved
@LilyFoote LilyFoote changed the title Refs #31300 -- Add support for function-based virtual fields on Oracle Refs #31300 -- Add support for function-based virtual fields Aug 30, 2023
@LilyFoote
Copy link
Contributor Author

Can we make the error nicer for now? This feels like something we can try to find a solution for in Django 5.1 to me.

Does explicitly registering the lookup with GeneratedField resolve the problem? In that case we might be able to document that as a workaround for now.

@felixxm
Copy link
Member

felixxm commented Sep 5, 2023

Can we make the error nicer for now?

IMO, no, I don't know how we would detect that.

Does explicitly registering the lookup with GeneratedField resolve the problem?

Not really as registering all class-related lookups on GeneratedField will create many conflicts 😞 Since Django 4.2 we can register lookups on field instances. We could (theoretically) register lookups from the output_field class in GeneratedField.contribute_to_class(), however this will force users to always define GeneratedField.output_field and this is just a theory 😅 .

@felixxm
Copy link
Member

felixxm commented Sep 5, 2023

Can we make the error nicer for now?

IMO, no, I don't know how we would detect that.

Does explicitly registering the lookup with GeneratedField resolve the problem?

Not really as registering all class-related lookups on GeneratedField will create many conflicts 😞 Since Django 4.2 we can register lookups on field instances. We could (theoretically) register lookups from the output_field class in GeneratedField.contribute_to_class(), however this will force users to always define GeneratedField.output_field and this is just a theory 😅 .

@felixxm
Copy link
Member

felixxm commented Sep 5, 2023

@pauloxnet Can you check the following patch?

diff --git a/django/db/models/fields/generated.py b/django/db/models/fields/generated.py
index 56a2854d3c..8bf6969f9d 100644
--- a/django/db/models/fields/generated.py
+++ b/django/db/models/fields/generated.py
@@ -44,6 +44,8 @@ class GeneratedField(Field):
             if self._output_field is not None
             else self._resolved_expression.output_field
         )
+        for lookup_name, lookup in self.output_field.get_class_lookups().items():
+            self.register_lookup(lookup, lookup_name=lookup_name)
 
     def generated_sql(self, connection):
         return self._resolved_expression.as_sql(

@pauloxnet
Copy link
Contributor

@pauloxnet Can you check the following patch?

I'll try it ASAP

@pauloxnet
Copy link
Contributor

@pauloxnet Can you check the following patch?

diff --git a/django/db/models/fields/generated.py b/django/db/models/fields/generated.py
index 56a2854d3c..8bf6969f9d 100644
--- a/django/db/models/fields/generated.py
+++ b/django/db/models/fields/generated.py
@@ -44,6 +44,8 @@ class GeneratedField(Field):
             if self._output_field is not None
             else self._resolved_expression.output_field
         )
+        for lookup_name, lookup in self.output_field.get_class_lookups().items():
+            self.register_lookup(lookup, lookup_name=lookup_name)
 
     def generated_sql(self, connection):
         return self._resolved_expression.as_sql(

It worked 👍🏻

>>> from geometricfigures.models import Document
>>> from django.contrib.postgres import search
>>> str(Document.objects.filter(search_vector=search.SearchQuery("deadline", config="english")).only("id").query)
'SELECT "geometricfigures_document"."id" FROM "geometricfigures_document" WHERE "geometricfigures_document"."search_vector" @@ (plainto_tsquery(english::regconfig, deadline))'
>>> str(Document.objects.filter(vector=search.SearchQuery("deadline", config="english")).only("id").query)
'SELECT "geometricfigures_document"."id" FROM "geometricfigures_document" WHERE "geometricfigures_document"."vector" @@ (plainto_tsquery(english::regconfig, deadline))'
>>> Document.objects.filter(vector=search.SearchQuery("deadline", config="english")).only("id")
<QuerySet [<Document: Document object (2)>]>
>>> Document.objects.filter(search_vector=search.SearchQuery("deadline", config="english")).only("id")
<QuerySet [<Document: Document object (2)>]>

@felixxm
Copy link
Member

felixxm commented Sep 5, 2023

It worked 👍🏻

Thanks for checking 👍

docs/ref/models/fields.txt Outdated Show resolved Hide resolved
docs/ref/models/fields.txt Outdated Show resolved Hide resolved
@felixxm felixxm force-pushed the ticket_31300 branch 3 times, most recently from 97717da to 6ce7c09 Compare September 6, 2023 10:18
@pauloxnet
Copy link
Contributor

I did further tests locally only finding problems for non-immutable functions in PostgreSQL. Apart from the documentation suggestions I've already sent, I have nothing more to add. Great job to all contributors, I think this is another great feature added to Django.

@felixxm felixxm force-pushed the ticket_31300 branch 2 times, most recently from fe89d97 to c48c0f7 Compare September 6, 2023 12:08
@felixxm
Copy link
Member

felixxm commented Sep 6, 2023

We're almost there 😪 only docs left 🚀 I'll continue later today/tomorrow.

@felixxm felixxm changed the title Refs #31300 -- Add support for function-based virtual fields Fixed #31300 -- Added GeneratedField model field. Sep 6, 2023
@felixxm
Copy link
Member

felixxm commented Sep 6, 2023

Squashed commits and pushed edits to release notes.

Thanks Adam Johnson and Paolo Melchiorre for reviews.

Co-Authored-By: Lily Foote <code@lilyf.org>
Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com>
@felixxm
Copy link
Member

felixxm commented Sep 7, 2023

@jpnauta Thanks 👍 Welcome aboard 👍

@LilyFoote Thanks for pushing this to the finish line 🥇

@felixxm felixxm merged commit f333e35 into django:main Sep 7, 2023
12 of 30 checks passed
@LilyFoote LilyFoote deleted the ticket_31300 branch September 7, 2023 09:43
Comment on lines +1262 to +1264
Since the database always computed the value, the object must be reloaded
to access the new value after :meth:`~Model.save()`, for example, by using
:meth:`~Model.refresh_from_db()`.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this always true? I'm wondering if for databases supporting RETURNING we can/do update the instance to make a refresh unnecessary?

Copy link
Member

Choose a reason for hiding this comment

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

Theoretically, we could use UPDATE ... RETURNING but let's leave some new features/cleanups for Django 5.1 😉

@jpnauta
Copy link
Contributor

jpnauta commented Sep 11, 2023

Thanks @LilyFoote @felixxm for pushing this through the finish line! It was a pleasure collaborating with you both 🥳

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
7 participants