**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.
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>
* 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>
* owner: nobody => Paolo Melchiorre
* status: new => assigned
* has_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/34877#comment:3>
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>
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/34877#comment:5>
* 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>
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>