[Django] #34877: KeyError for output_field in GeneratedField

2 views
Skip to first unread message

Django

unread,
Sep 27, 2023, 2:06:39 PM9/27/23
to django-...@googlegroups.com
#34877: KeyError for output_field in GeneratedField
-------------------------------------+-------------------------------------
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 |
-------------------------------------+-------------------------------------
Trying to get SQL code for a migrations I receive a `KeyEorr`

**Model**

{{{#!python
from decimal import Decimal
from django.db import models
from django.db.models import F, Value as V
from django.db.models.functions import Round

class Item(models.Model):
price = models.DecimalField(max_digits=7, decimal_places=2)
vat_price = models.GeneratedField(
db_persist=True,
expression=Round(F("price") * V(Decimal("1.22")), 2),
output_field=models.DecimalField(max_digits=8, decimal_places=2),
)
}}}

**Step**

{{{#!bash
$ python -m manage makemigrations
$ python -m manage sqlmigrate shop 0001
}}}

**Traceback**

{{{#!pycon
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/home/paulox/Projects/generatedfield/manage.py", line 22, in
<module>
main()
File "/home/paulox/Projects/generatedfield/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/core/management/__init__.py", line 442, in
execute_from_command_line
utility.execute()
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/core/management/__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/core/management/base.py", line 412, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/core/management/commands/sqlmigrate.py", line 38, in
execute
return super().execute(*args, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/core/management/base.py", line 458, in execute
output = self.handle(*args, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/core/management/commands/sqlmigrate.py", line 80, in
handle
sql_statements = loader.collect_sql(plan)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/db/migrations/loader.py", line 381, in collect_sql
state = migration.apply(state, schema_editor, collect_sql=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/db/migrations/migration.py", line 132, in apply
operation.database_forwards(
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/db/migrations/operations/models.py", line 96, in
database_forwards
schema_editor.create_model(model)
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/db/backends/base/schema.py", line 506, in create_model
self.deferred_sql.extend(self._model_indexes_sql(model))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/db/backends/base/schema.py", line 1595, in
_model_indexes_sql
output.extend(self._field_indexes_sql(model, field))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/db/backends/postgresql/schema.py", line 63, in
_field_indexes_sql
like_index_statement = self._create_like_index_sql(model, field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/db/backends/postgresql/schema.py", line 88, in
_create_like_index_sql
db_type = field.db_type(connection=self.connection)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/db/models/fields/__init__.py", line 879, in db_type
return column_type % data
~~~~~~~~~~~~^~~~~~
File "/home/paulox/Projects/generatedfield/.venv/lib/python3.11/site-
packages/django/utils/datastructures.py", line 280, in __getitem__
value = super().__getitem__(key)
^^^^^^^^^^^^^^^^^^^^^^^^
KeyError: 'max_digits'
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/34877>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Sep 27, 2023, 3:14:40 PM9/27/23
to django-...@googlegroups.com
#34877: KeyError for output_field in GeneratedField
-------------------------------------+-------------------------------------
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:

New description:

Trying to get SQL code for a migration I receive a `KeyError`.

**Model**

Example of a model with a `GenratedField`.

{{{#!python
from decimal import Decimal
from django.db import models
from django.db.models import F, Value as V
from django.db.models.functions import Round

class Item(models.Model):
price = models.DecimalField(max_digits=7, decimal_places=2)
vat_price = models.GeneratedField(
db_persist=True,
expression=Round(F("price") * V(Decimal("1.22")), 2),
output_field=models.DecimalField(max_digits=8, decimal_places=2),
)
}}}

**Step**

Generate the migration file:

{{{#!bash
$ python -m manage makemigrations
}}}

Steps to generate the error:

{{{#!bash
$ python -m manage sqlmigrate shop 0001
}}}

Similar error with another command:

{{{#!bash
$ python -m manage migrate shop 0001
}}}

**Traceback**

**Expected result**

{{{#!sql
BEGIN;
--
-- Create model Item
--
CREATE TABLE "shop_item" (
"id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
"price" numeric(7, 2) NOT NULL,
"vat_price" numeric(8, 2) GENERATED ALWAYS AS (ROUND(("price" * 1.22),
2)) STORED
);
COMMIT;
}}}

--

--
Ticket URL: <https://code.djangoproject.com/ticket/34877#comment:1>

Django

unread,
Sep 27, 2023, 3:24:40 PM9/27/23
to django-...@googlegroups.com
#34877: KeyError for output_field in GeneratedField
-------------------------------------+-------------------------------------
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: Accepted
generated, output_field |

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* stage: Unreviewed => Accepted


Comment:

Seems like we missed a `db_type_parameters` override

{{{#!diff
diff --git a/django/db/models/fields/generated.py
b/django/db/models/fields/generated.py
index deb5875638..5fbd4c4fdd 100644
--- a/django/db/models/fields/generated.py
+++ b/django/db/models/fields/generated.py
@@ -161,3 +161,6 @@ def get_internal_type(self):

def db_parameters(self, connection):
return self.output_field.db_parameters(connection)
+
+ def db_type_parameters(self, connection):
+ return self.output_field.db_type_parameters(connection)
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/34877#comment:2>

Django

unread,
Sep 27, 2023, 6:05:23 PM9/27/23
to django-...@googlegroups.com
#34877: KeyError for output_field in GeneratedField
-------------------------------------+-------------------------------------
Reporter: Paolo Melchiorre | Owner: Paolo
| Melchiorre
Type: Bug | Status: assigned

Component: Database layer | Version: 5.0
(models, ORM) |
Severity: Release blocker | Resolution:
Keywords: field, database, | Triage Stage: Accepted
generated, output_field |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Paolo Melchiorre):

* owner: nobody => Paolo Melchiorre
* status: new => assigned
* has_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/34877#comment:3>

Django

unread,
Sep 27, 2023, 6:08:00 PM9/27/23
to django-...@googlegroups.com
#34877: KeyError for output_field in GeneratedField
-------------------------------------+-------------------------------------
Reporter: Paolo Melchiorre | Owner: Paolo
| Melchiorre
Type: Bug | Status: assigned
Component: Database layer | Version: 5.0
(models, ORM) |
Severity: Release blocker | Resolution:
Keywords: field, database, | Triage Stage: Accepted
generated, output_field |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Paolo Melchiorre):

Replying to [comment:2 Simon Charette]:


> Seems like we missed a `db_type_parameters` override

Thanks again Simon.

I opened a [https://github.com/django/django/pull/17314 PR] based on your
suggestion.

--
Ticket URL: <https://code.djangoproject.com/ticket/34877#comment:4>

Django

unread,
Sep 27, 2023, 11:44:05 PM9/27/23
to django-...@googlegroups.com
#34877: KeyError for output_field in GeneratedField
-------------------------------------+-------------------------------------
Reporter: Paolo Melchiorre | Owner: Paolo
| Melchiorre
Type: Bug | Status: assigned
Component: Database layer | Version: 5.0
(models, ORM) |
Severity: Release blocker | Resolution:
Keywords: field, database, | Triage Stage: Ready for
generated, output_field | checkin

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/34877#comment:5>

Django

unread,
Sep 28, 2023, 2:12:31 AM9/28/23
to django-...@googlegroups.com
#34877: KeyError for output_field in GeneratedField
-------------------------------------+-------------------------------------
Reporter: Paolo Melchiorre | Owner: Paolo
| Melchiorre
Type: Bug | Status: closed

Component: Database layer | Version: 5.0
(models, ORM) |
Severity: Release blocker | Resolution: fixed

Keywords: field, database, | Triage Stage: Ready for
generated, output_field | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak <felisiak.mariusz@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"e7e8eb44a30bcab004a582760752b5eb3fcd6e91" e7e8eb44]:
{{{
#!CommitTicketReference repository=""
revision="e7e8eb44a30bcab004a582760752b5eb3fcd6e91"
Fixed #34877 -- Fixed migrations crash when adding GeneratedField with
output_field with params.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/34877#comment:6>

Django

unread,
Sep 28, 2023, 2:12:59 AM9/28/23
to django-...@googlegroups.com
#34877: KeyError for output_field in GeneratedField
-------------------------------------+-------------------------------------
Reporter: Paolo Melchiorre | Owner: Paolo
| Melchiorre
Type: Bug | Status: closed
Component: Database layer | Version: 5.0
(models, ORM) |
Severity: Release blocker | Resolution: fixed
Keywords: field, database, | Triage Stage: Ready for
generated, output_field | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Mariusz Felisiak <felisiak.mariusz@…>):

In [changeset:"0f9d07398d487868f3ac9bc2e2dd3efef984a49c" 0f9d0739]:
{{{
#!CommitTicketReference repository=""
revision="0f9d07398d487868f3ac9bc2e2dd3efef984a49c"
[5.0.x] Fixed #34877 -- Fixed migrations crash when adding GeneratedField
with output_field with params.

Backport of e7e8eb44a30bcab004a582760752b5eb3fcd6e91 from main
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/34877#comment:7>

Reply all
Reply to author
Forward
0 new messages