Re: [Django] #34946: Adding a field with default and db_default drops database level DEFAULT

2023-11-05 Thread Django
#34946: Adding a field with default and db_default drops database level DEFAULT
-+-
 Reporter:  Simon Charette   |Owner:  Simon
 |  Charette
 Type:  Bug  |   Status:  assigned
Component:  Migrations   |  Version:  5.0
 Severity:  Release blocker  |   Resolution:
 Keywords:  sql, default,| Triage Stage:  Accepted
  migrations |
Has patch:  1|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-
Changes (by Paolo Melchiorre):

 * cc: Paolo Melchiorre (added)
 * keywords:   => sql, default, migrations


-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018ba37bfabb-6988391a-92fc-4c04-b909-074690264aeb-00%40eu-central-1.amazonses.com.


Re: [Django] #34457: makemigrations --check no longer prints the changes

2023-11-05 Thread Django
#34457: makemigrations --check no longer prints the changes
-+-
 Reporter:  David Sanders|Owner:  Adam
 |  Johnson
 Type:  Bug  |   Status:  assigned
Component:  Migrations   |  Version:  4.2
 Severity:  Release blocker  |   Resolution:
 Keywords:   | Triage Stage:  Ready for
 |  checkin
Has patch:  1|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-
Changes (by Jacob Walls):

 * owner:  nobody => Adam Johnson
 * status:  new => assigned
 * stage:  Accepted => Ready for checkin


Comment:

 [https://github.com/django/django/pull/17448 new PR]

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018ba1c4b3db-dfb8601b-2734-4684-824f-36eeffc01460-00%40eu-central-1.amazonses.com.


Re: [Django] #34457: makemigrations --check no longer prints the changes

2023-11-05 Thread Django
#34457: makemigrations --check no longer prints the changes
-+
 Reporter:  David Sanders|Owner:  nobody
 Type:  Bug  |   Status:  new
Component:  Migrations   |  Version:  4.2
 Severity:  Release blocker  |   Resolution:
 Keywords:   | Triage Stage:  Accepted
Has patch:  1|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+
Changes (by Adam Johnson):

 * has_patch:  0 => 1


-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018ba183ec4e-d441921d-dc03-45fe-9e97-cbf811c98d7c-00%40eu-central-1.amazonses.com.


Re: [Django] #34457: makemigrations --check no longer prints the changes

2023-11-05 Thread Django
#34457: makemigrations --check no longer prints the changes
-+
 Reporter:  David Sanders|Owner:  nobody
 Type:  Bug  |   Status:  new
Component:  Migrations   |  Version:  4.2
 Severity:  Release blocker  |   Resolution:
 Keywords:   | Triage Stage:  Accepted
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+
Changes (by Adam Johnson):

 * type:  Cleanup/optimization => Bug
 * severity:  Normal => Release blocker


Comment:

 Marking as a release blocker because I consider it a regression, as
 discussed on the forum.

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018ba17f4c13-b6d5b4c6-8fc9-4043-92a1-25349b540497-00%40eu-central-1.amazonses.com.


Re: [Django] #34946: Adding a field with default and db_default drops database level DEFAULT

2023-11-05 Thread Django
#34946: Adding a field with default and db_default drops database level DEFAULT
-+-
 Reporter:  Simon Charette   |Owner:  Simon
 |  Charette
 Type:  Bug  |   Status:  assigned
Component:  Migrations   |  Version:  5.0
 Severity:  Release blocker  |   Resolution:
 Keywords:   | Triage Stage:  Accepted
Has patch:  1|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-
Changes (by Mariusz Felisiak):

 * owner:  nobody => Simon Charette
 * stage:  Unreviewed => Accepted


Comment:

 Thanks!

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018ba1687458-63570994-8e46-4417-b3e9-827547232721-00%40eu-central-1.amazonses.com.


Re: [Django] #14611: Added dedicated option to test.Client methods (other than get()) for passing query parameters.

2023-11-05 Thread Django
#14611: Added dedicated option to test.Client methods (other than get()) for
passing query parameters.
---+---
 Reporter:  Jari Pennanen  |Owner:  Tom Carrick
 Type:  New feature|   Status:  assigned
Component:  Testing framework  |  Version:  1.2
 Severity:  Normal |   Resolution:
 Keywords: | Triage Stage:  Accepted
Has patch:  1  |  Needs documentation:  0
  Needs tests:  0  |  Patch needs improvement:  0
Easy pickings:  0  |UI/UX:  0
---+---
Changes (by Tom Carrick):

 * has_patch:  0 => 1


Comment:

 [https://github.com/django/django/pull/17447 PR]

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018ba0a75964-7334e316-4c88-47f8-abac-1600c3dcc6bc-00%40eu-central-1.amazonses.com.


Re: [Django] #34946: Adding a field with default and db_default drops database level DEFAULT

2023-11-05 Thread Django
#34946: Adding a field with default and db_default drops database level DEFAULT
-+--
 Reporter:  Simon Charette   |Owner:  nobody
 Type:  Bug  |   Status:  assigned
Component:  Migrations   |  Version:  5.0
 Severity:  Release blocker  |   Resolution:
 Keywords:   | Triage Stage:  Unreviewed
Has patch:  1|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+--
Changes (by Simon Charette):

 * has_patch:  0 => 1


-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018ba0a12d53-f70bf82d-9805-49fe-b374-6956e61c1046-00%40eu-central-1.amazonses.com.


Re: [Django] #28900: QuerySet.values() and values_list() for compound queries fails with annotation.

2023-11-05 Thread Django
#28900: QuerySet.values() and values_list() for compound queries fails with
annotation.
-+-
 Reporter:  elliott-omosheye |Owner:  (none)
 Type:  Bug  |   Status:  new
Component:  Database layer   |  Version:  1.11
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:  union, values| Triage Stage:  Accepted
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-
Changes (by Tom Carrick):

 * cc: Tom Carrick (added)


-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018ba09b622c-042cd2ff-37ae-4178-b331-0195c98dd6bd-00%40eu-central-1.amazonses.com.


[Django] #34946: Adding a field with default and db_default drops database level DEFAULT

2023-11-05 Thread Django
#34946: Adding a field with default and db_default drops database level DEFAULT
---+--
   Reporter:  Simon Charette   |  Owner:  nobody
   Type:  Bug  | Status:  assigned
  Component:  Migrations   |Version:  5.0
   Severity:  Release blocker  |   Keywords:
   Triage Stage:  Unreviewed   |  Has patch:  0
Needs documentation:  0|Needs tests:  0
Patch needs improvement:  0|  Easy pickings:  0
  UI/UX:  0|
---+--
 [https://docs.djangoproject.com/en/dev/ref/models/fields/#db-default The
 documentation] for `Field.db_default` states

 > If both `db_default` and `Field.default` are set, `default` will take
 precedence when creating instances in Python code. `db_default` will still
 be set at the database level and will be used when inserting rows outside
 of the ORM or when adding a new field in a migration.

 However adding a field with both results in the following SQL

 {{{#!sql
 ALTER TABLE "foo" ADD COLUMN "bar" integer DEFAULT 42 NOT NULL;
 ALTER TABLE "foo" ALTER COLUMN "bar" DROP DEFAULT;
 }}}

 The `DEFAULT` should never be dropped if the field has a `db_default`
 defined.

 The following patch reproduces and demonstrate
 
[https://github.com/django/django/commit/7414704e88d73dafbcfbb85f9bc54cb6111439d3
 #diff-
 7cc40f1cb85a8f19c80b2e901626d78e4729047dbbb0ed52861f5894ff688115R1673-R1716
 why the test] that intended to cover this case didn't catch it.

 {{{#!diff
 diff --git a/tests/migrations/test_operations.py
 b/tests/migrations/test_operations.py
 index d58da8b7ac..57a9086c19 100644
 --- a/tests/migrations/test_operations.py
 +++ b/tests/migrations/test_operations.py
 @@ -1692,15 +1692,22 @@ def test_add_field_both_defaults(self):
  field = new_state.models[app_label, "pony"].fields["height"]
  self.assertEqual(field.default, 3)
  self.assertEqual(field.db_default, Value(4))
 -project_state.apps.get_model(app_label,
 "pony").objects.create(weight=4)
 +pre_pony_pk = (
 +project_state.apps.get_model(app_label,
 "pony").objects.create(weight=4).pk
 +)
  self.assertColumnNotExists(table_name, "height")
  # Add field.
  with connection.schema_editor() as editor:
  operation.database_forwards(app_label, editor, project_state,
 new_state)
  self.assertColumnExists(table_name, "height")
 +post_pony_pk = (
 +project_state.apps.get_model(app_label,
 "pony").objects.create(weight=10).pk
 +)
  new_model = new_state.apps.get_model(app_label, "pony")
 -old_pony = new_model.objects.get()
 -self.assertEqual(old_pony.height, 4)
 +pre_pony = new_model.objects.get(pk=pre_pony_pk)
 +self.assertEqual(pre_pony.height, 4)
 +post_pony = new_model.objects.get(pk=post_pony_pk)
 +self.assertEqual(post_pony.height, 4)
  new_pony = new_model.objects.create(weight=5)
  if not connection.features.can_return_columns_from_insert:
  new_pony.refresh_from_db()
 diff --git a/tests/schema/tests.py b/tests/schema/tests.py
 index 20a00e29f7..80fdead190 100644
 --- a/tests/schema/tests.py
 +++ b/tests/schema/tests.py
 @@ -2257,6 +2257,24 @@ class Meta:
  columns = self.column_classes(AuthorDbDefault)
  self.assertEqual(columns["renamed_year"][1].default, "1985")

 +@isolate_apps("schema")
 +def test_add_field_both_defaults_preserves_db_default(self):
 +class Author(Model):
 +class Meta:
 +app_label = "schema"
 +
 +#self.isolated_local_models = [Author]
 +with connection.schema_editor() as editor:
 +editor.create_model(Author)
 +
 +field = IntegerField(default=1985, db_default=1988)
 +field.set_attributes_from_name("birth_year")
 +field.model = Author
 +with connection.schema_editor() as editor:
 +editor.add_field(Author, field)
 +columns = self.column_classes(Author)
 +self.assertEqual(columns["birth_year"][1].default, "1988")
 +
  @skipUnlessDBFeature(
  "supports_column_check_constraints",
 "can_introspect_check_constraints"
  )
 }}}

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 

Re: [Django] #28900: QuerySet.values() and values_list() for compound queries fails with annotation.

2023-11-05 Thread Django
#28900: QuerySet.values() and values_list() for compound queries fails with
annotation.
-+-
 Reporter:  elliott-omosheye |Owner:  (none)
 Type:  Bug  |   Status:  new
Component:  Database layer   |  Version:  1.11
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:  union, values| Triage Stage:  Accepted
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-
Changes (by David Sanders):

 * cc: David Sanders (added)


Comment:

 If it helps, while checking if #34945 was a duplicate of this I was able
 to boil down the failure to this simple example:

 {{{
 class Foo(Model):
 name = CharField()

 class Bar(Model):
 name = CharField()

 qs = (
 Foo.objects.annotate(alias=F("name"))
 .union(Bar.objects.annotate(alias=F("name")))
 .values("alias")
 )
 print(qs)
 }}}

 gives

 {{{
 
 }}}

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018ba03184f9-1dea6a59-7b25-4b63-be82-727c6218e1a4-00%40eu-central-1.amazonses.com.


Re: [Django] #34945: annotate -> union -> values gives wrong values

2023-11-05 Thread Django
#34945: annotate -> union -> values gives wrong values
-+-
 Reporter:  Tom Carrick  |Owner:  nobody
 Type:  Bug  |   Status:  closed
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:  duplicate
 Keywords:   | Triage Stage:
 |  Unreviewed
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-
Changes (by David Sanders):

 * status:  new => closed
 * resolution:   => duplicate


Comment:

 Duplicate of #28900

 Ha no worries Tom  I suspect it's the same. Let's close as a duplicate
 for now… keep an eye on solutions for #28900 to see if the patches work
 for you as well.

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018ba02fafc8-b79b6535-4143-42e3-a370-49225ee4c589-00%40eu-central-1.amazonses.com.


Re: [Django] #34945: annotate -> union -> values gives wrong values

2023-11-05 Thread Django
#34945: annotate -> union -> values gives wrong values
-+-
 Reporter:  Tom Carrick  |Owner:  nobody
 Type:  Bug  |   Status:  new
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:
 |  Unreviewed
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-

Comment (by Tom Carrick):

 Oops! Actually I realised I was on 4.2, this seems to be working for me on
 dev, so it's more likely a duplicate of
 [https://code.djangoproject.com/ticket/28553 #28553].

 But your version doesn't work on dev? Hard to say but they seem similar,
 the fix could be the same.

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018b9fc88c4a-2d0624c3-9c1e-439d-8fb3-5cd103cdd891-00%40eu-central-1.amazonses.com.


Re: [Django] #34945: annotate -> union -> values gives wrong values

2023-11-05 Thread Django
#34945: annotate -> union -> values gives wrong values
-+-
 Reporter:  Tom Carrick  |Owner:  nobody
 Type:  Bug  |   Status:  new
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:
 |  Unreviewed
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-

Comment (by David Sanders):

 Duplicate of #28900? 樂

 I've managed to boil this down the following example:

 {{{
 class Foo(Model):
 name = CharField()

 class Bar(Model):
 name = CharField()

 qs = (
 Foo.objects.annotate(alias=F("name"))
 .union(Bar.objects.annotate(alias=F("name")))
 .values("alias")
 )
 print(qs)
 }}}

 gives

 {{{
 
 }}}

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018b9fbc3dce-48427a22-66c1-49da-92bb-b346305e4a7f-00%40eu-central-1.amazonses.com.


[Django] #34945: annotate -> union -> values gives wrong values

2023-11-05 Thread Django
#34945: annotate -> union -> values gives wrong values
-+-
   Reporter:  Tom|  Owner:  nobody
  Carrick|
   Type:  Bug| Status:  new
  Component:  Database   |Version:  4.2
  layer (models, ORM)|
   Severity:  Normal |   Keywords:
   Triage Stage: |  Has patch:  0
  Unreviewed |
Needs documentation:  0  |Needs tests:  0
Patch needs improvement:  0  |  Easy pickings:  0
  UI/UX:  0  |
-+-
 With the following code:

 {{{
 import uuid

 from django.conf import settings
 from django.contrib.auth import get_user_model
 from django.db import models
 from django.db.models.functions import Cast


 class DocumentQuerySet(models.QuerySet):
 def for_user(self, user):
 return self.filter(things__user=user).union(
 self.filter(other_things__user=user)
 )


 class Document(models.Model):
 name = models.CharField()
 id = models.UUIDField(default=uuid.uuid4, primary_key=True)

 objects = DocumentQuerySet().as_manager()


 class Thing(models.Model):
 user = models.ForeignKey(
 settings.AUTH_USER_MODEL, related_name="things",
 on_delete=models.CASCADE
 )
 document = models.ForeignKey(
 Document, related_name="things", on_delete=models.CASCADE
 )


 class OtherThing(models.Model):
 user = models.ForeignKey(
 settings.AUTH_USER_MODEL, related_name="other_things",
 on_delete=models.CASCADE
 )
 document = models.ForeignKey(
 Document, related_name="other_things", on_delete=models.CASCADE
 )


 def broken():
 user = get_user_model().objects.first()
 return Document.objects.annotate(
 pk_str=Cast("pk", output_field=models.CharField())
 ).for_user(user).values_list("pk_str", flat=True)
 }}}

 Running `broken()`, I would expect to say the stringified UUIDs from the
 Document model. Instead I get the `name`s. It also happens when using
 `values()`. If not using either, it works just fine, and you can access
 `document.pk_str` and it works just fine. After playing with this, it
 seems to be because it's defined first in the model. If I move `id` to the
 top, it actually returns the UUIDs, without the cast being applied. The
 query (as far as I can tell from Django) looks fine:

 {{{
 (SELECT "testapp_document"."id" AS "col1", "testapp_document"."name" AS
 "col2", ("testapp_document"."id")::varchar AS "pk_str" FROM
 "testapp_document" INNER JOIN "testapp_thing" ON ("testapp_document"."id"
 = "testapp_thing"."document_id") WHERE "testapp_thing"."user_id" = 1)
 UNION (SELECT "testapp_document"."id" AS "col1", "testapp_document"."name"
 AS "col2", ("testapp_document"."id")::varchar AS "pk_str" FROM
 "testapp_document" INNER JOIN "testapp_otherthing" ON
 ("testapp_document"."id" = "testapp_otherthing"."document_id") WHERE
 "testapp_otherthing"."user_id" = 1)
 }}}

 And logged from Postgres also looks correct:
 {{{
 (SELECT "testapp_document"."name" AS "col1", "testapp_document"."id" AS
 "col2", ("testapp_document"."id")::varchar AS "pk_str" FROM
 "testapp_document" INNER JOIN "testapp_thing" ON ("testapp_document"."id"
 = "testapp_thing"."document_id") WHERE "testapp_thing"."user_id" = 1)
 UNION (SELECT "testapp_document"."name" AS "col1", "testapp_document"."id"
 AS "col2", ("testapp_document"."id")::varchar AS "pk_str" FROM
 "testapp_document" INNER JOIN "testapp_otherthing" ON
 ("testapp_document"."id" = "testapp_otherthing"."document_id") WHERE
 "testapp_otherthing"."user_id" = 1) LIMIT 21
 }}}

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018b9f84e49f-4e20db75-bf37-4033-8bd3-62dc39ed0b95-00%40eu-central-1.amazonses.com.


Re: [Django] #34944: Missing or misinferred attributes in output fields of generated fields

2023-11-05 Thread Django
#34944: Missing or misinferred attributes in output fields of generated fields
-+-
 Reporter:  Paolo Melchiorre |Owner:  nobody
 Type:  Bug  |   Status:  new
Component:  Database layer   |  Version:  5.0
  (models, ORM)  |
 Severity:  Release blocker  |   Resolution:
 Keywords:  field, database, | Triage Stage:
  generated, output_field|  Unreviewed
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-
Description changed by Paolo Melchiorre:

Old description:

> Continuing with my experiments with the generated fields I found these
> two error situations which I reported together because they are very
> connected and could lead to a single solution.
>
> I do not rule out that there are other examples of use of the generated
> fields that could lead to the same errors and if they come to mind,
> please add them in the comments.
>
> == Misinferred attributes
>
> In the common example of a field generated as a concatenation of two
> CharField in a Model:
>
> {{{
> #!python
> class Person(models.Model):
> first_name = models.CharField(max_length=255)
> last_name = models.CharField(max_length=255)
> full_name = models.GeneratedField(
> expression=Concat(
> "first_name", models.Value(" "), "last_name"
> ),
> db_persist=True,
> )
> }}}
>
> The SQL code for the generated column has an automatically inferred max
> length of only 255 characters (`varchar(255)`), while the field should be
> able to contain strings of 511 characters (`varchar(511)`):
>
> {{{
> #!sql
> CREATE TABLE "community_person" (
> "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
> "first_name" varchar(255) NOT NULL,
> "last_name" varchar(255) NOT NULL,
> "full_name" varchar(255) GENERATED ALWAYS AS (
> COALESCE("first_name", '') ||
> COALESCE(COALESCE(' ', '') ||
> COALESCE("last_name", ''), '')
> ) STORED
> );
> }}}
>
>  Proposal
>
> To solve the problem you could alternatively:
>
> a. make the maximum length extraction process smarter for the
> automatically created output fields
> b. mandatorily require specifying the output field when some of the
> fields involved could lead to situations like the ones above
>

> == Missing attributes
>
> If in the previous example, I explicitly specify the output field without
> attributes, the migration is generated without generating errors:
>
> {{{
> #!python
> class Person(models.Model):
> first_name = models.CharField(max_length=255)
> last_name = models.CharField(max_length=255)
> full_name = models.GeneratedField(
> expression=Concat(
> "first_name", models.Value(" "), "last_name"
> ),
> db_persist=True,
> output_field=models.CharField(),
> )
> }}}
>
> The SQL code contains an incorrect `varchar(None)` type:
>
> {{{
> #!sql
> CREATE TABLE "community_person" (
> "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
> "first_name" varchar(255) NOT NULL,
> "last_name" varchar(255) NOT NULL,
> "full_name" varchar(None) GENERATED ALWAYS AS (
> COALESCE("first_name", '') ||
> COALESCE(COALESCE(' ', '') ||
> COALESCE("last_name", ''), '')
> ) STORED
> );
> }}}
>
> which will generate an error when trying to apply the migration to the
> database:
>
> {{{
> #!console
> sqlite3.OperationalError: near "None": syntax error
> }}}
>

>  Proposal
>
> To solve the problem you could alternatively:
>
> a. make the SQL code generation process smarter so as to generate working
> SQL code
> b. request to specify mandatory attributes for the output fields raising
> an error in the migration creation phase
>
> == Cumulative proposal
>
> To solve both problems shown above, given the little time remaining
> before the release of the stable version of Django 5, the two most
> drastic solutions from both of the above proposals could be adopted.
>
>  Required output field
>
> Always require specifying the output field ''(except when you are sure
> that the extracted type cannot generate error situations?)''
>
> Example of error message:
> {{{
> #!console
> django.core.exceptions.FieldError: Expression doesn't contain an explicit
> type. You must set output_field.
> }}}
>
>  Required attributes
> Request to specify mandatory attributes for the output fields raising an
> error in the migration creation phase.
>
> {{{
> #!console
> $ python3 -m manage makemigrations
> SystemCheckError: System check identified some issues:
>
> ERRORS:
> community.Person.full_name: 

[Django] #34944: Missing or misinferred attributes in output fields of generated fields

2023-11-05 Thread Django
#34944: Missing or misinferred attributes in output fields of generated fields
-+-
   Reporter:  Paolo  |  Owner:  nobody
  Melchiorre |
   Type:  Bug| Status:  new
  Component:  Database   |Version:  5.0
  layer (models, ORM)|
   Severity:  Release|   Keywords:  field, database,
  blocker|  generated, output_field
   Triage Stage: |  Has patch:  0
  Unreviewed |
Needs documentation:  0  |Needs tests:  0
Patch needs improvement:  0  |  Easy pickings:  0
  UI/UX:  0  |
-+-
 Continuing with my experiments with the generated fields I found these two
 error situations which I reported together because they are very connected
 and could lead to a single solution.

 I do not rule out that there are other examples of use of the generated
 fields that could lead to the same errors and if they come to mind, please
 add them in the comments.

 == Misinferred attributes

 In the common example of a field generated as a concatenation of two
 CharField in a Model:

 {{{
 #!python
 class Person(models.Model):
 first_name = models.CharField(max_length=255)
 last_name = models.CharField(max_length=255)
 full_name = models.GeneratedField(
 expression=Concat(
 "first_name", models.Value(" "), "last_name"
 ),
 db_persist=True,
 )
 }}}

 The SQL code for the generated column has an automatically inferred max
 length of only 255 characters (`varchar(255)`), while the field should be
 able to contain strings of 511 characters (`varchar(511)`):

 {{{
 #!sql
 CREATE TABLE "community_person" (
 "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
 "first_name" varchar(255) NOT NULL,
 "last_name" varchar(255) NOT NULL,
 "full_name" varchar(255) GENERATED ALWAYS AS (
 COALESCE("first_name", '') ||
 COALESCE(COALESCE(' ', '') ||
 COALESCE("last_name", ''), '')
 ) STORED
 );
 }}}

  Proposal

 To solve the problem you could alternatively:

 a. make the maximum length extraction process smarter for the
 automatically created output fields
 b. mandatorily require specifying the output field when some of the fields
 involved could lead to situations like the ones above


 == Missing attributes

 If in the previous example, I explicitly specify the output field without
 attributes, the migration is generated without generating errors:

 {{{
 #!python
 class Person(models.Model):
 first_name = models.CharField(max_length=255)
 last_name = models.CharField(max_length=255)
 full_name = models.GeneratedField(
 expression=Concat(
 "first_name", models.Value(" "), "last_name"
 ),
 db_persist=True,
 output_field=models.CharField(),
 )
 }}}

 The SQL code contains an incorrect `varchar(None)` type:

 {{{
 #!sql
 CREATE TABLE "community_person" (
 "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
 "first_name" varchar(255) NOT NULL,
 "last_name" varchar(255) NOT NULL,
 "full_name" varchar(None) GENERATED ALWAYS AS (
 COALESCE("first_name", '') ||
 COALESCE(COALESCE(' ', '') ||
 COALESCE("last_name", ''), '')
 ) STORED
 );
 }}}

 which will generate an error when trying to apply the migration to the
 database:

 {{{
 #!console
 sqlite3.OperationalError: near "None": syntax error
 }}}


  Proposal

 To solve the problem you could alternatively:

 a. make the SQL code generation process smarter so as to generate working
 SQL code
 b. request to specify mandatory attributes for the output fields raising
 an error in the migration creation phase

 == Cumulative proposal

 To solve both problems shown above, given the little time remaining before
 the release of the stable version of Django 5, the two most drastic
 solutions from both of the above proposals could be adopted.

  Required output field

 Always require specifying the output field ''(except when you are sure
 that the extracted type cannot generate error situations?)''

 Example of error message:
 {{{
 #!console
 django.core.exceptions.FieldError: Expression doesn't contain an explicit
 type. You must set output_field.
 }}}

  Required attributes
 Request to specify mandatory attributes for the output fields raising an
 error in the migration creation phase.

 {{{
 #!console
 $ python3 -m manage makemigrations
 SystemCheckError: System check identified some issues:

 ERRORS:
 community.Person.full_name: (fields.E120) CharFields must define a
 'max_length' attribute.
 }}}

-- 
Ticket URL: 
Django 
The Web