#25417: decimal.InvalidOperation caused by Migrations and DecimalField()
-------------------------------------+-------------------------------------
     Reporter:  avorio               |                    Owner:  nobody
         Type:  Bug                  |                   Status:  closed
    Component:  Migrations           |                  Version:  1.8
     Severity:  Release blocker      |               Resolution:  needsinfo
     Keywords:  decimal,             |             Triage Stage:
  InvalidOperation, migrations       |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by avorio):

 I just reproduced this error again on a fresh new Django project using
 Python 3.4.3 and Django 1.8.4. I followed exactly the same steps using
 `django.db.backends.postgresql_psycopg2` as the database backend instead.

 Just to clarify, the only change in the field is from `max_digits=3` to
 `max_digits=5`. The default value continues the same `default=20.00`
 (which, by the way, would not be compatible with the first `max_digits`
 value).

 Here's the first migration:

 {{{
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals

 from django.db import models, migrations


 class Migration(migrations.Migration):

     dependencies = [
     ]

     operations = [
         migrations.CreateModel(
             name='Item',
             fields=[
                 ('id', models.AutoField(auto_created=True,
 primary_key=True, verbose_name='ID', serialize=False)),
                 ('tax_rate', models.DecimalField(help_text='VAT rate',
 decimal_places=2, blank=True, null=True, max_digits=3, default=20.0,
 verbose_name='tax rate (%)')),
             ],
         ),
     ]
 }}}

 And here's the second:

 {{{
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals

 from django.db import models, migrations


 class Migration(migrations.Migration):

     dependencies = [
         ('testapp', '0001_initial'),
     ]

     operations = [
         migrations.AlterField(
             model_name='item',
             name='tax_rate',
             field=models.DecimalField(decimal_places=2, help_text='VAT
 rate', verbose_name='tax rate (%)', default=20.0, max_digits=5,
 blank=True, null=True),
         ),
     ]
 }}}

 And here's the output of migrations:

 {{{
 (.venv)➜  mysite  python manage.py makemigrations
 Migrations for 'testapp':
   0001_initial.py:
     - Create model Item
 (.venv)➜  mysite  python manage.py migrate
 Operations to perform:
   Synchronize unmigrated apps: messages, staticfiles
   Apply all migrations: apython manage.py migratein, auth, contenttypes,
 sessions, testapp
 Synchronizing apps without migrations:
   Creating tables...
     Running deferred SQL...
   Installing custom SQL...
 Running migrations:
   Rendering model states... DONE
   Applying testapp.0001_initial... OK
 (.venv)➜  mysite  python manage.py makemigrations
 Migrations for 'testapp':
   0002_auto_20150917_0951.py:
     - Alter field tax_rate on item
 (.venv)➜  mysite  python manage.py migrate
 Operations to perform:
   Synchronize unmigrated apps: messages, staticfiles
   Apply all migrations: testapp, contenttypes, auth, sessions, apython
 manage.py migratein
 Synchronizing apps without migrations:
   Creating tables...
     Running deferred SQL...
   Installing custom SQL...
 Running migrations:
   Rendering model states... DONE
   Applying testapp.0002_auto_20150917_0951...Traceback (most recent call
 last):
   File "manage.py", line 10, in <module>
     execute_from_command_line(sys.argv)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/core/management/__init__.py", line 338, in
 execute_from_command_line
     utility.execute()
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/core/management/__init__.py", line 330, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/core/management/base.py", line 393, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/core/management/base.py", line 444, in execute
     output = self.handle(*args, **options)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/core/management/commands/migrate.py", line 222, in handle
     executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/db/migrations/executor.py", line 110, in migrate
     self.apply_migration(states[migration], migration, fake=fake,
 fake_initial=fake_initial)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/db/migrations/executor.py", line 148, in apply_migration
     state = migration.apply(state, schema_editor)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/db/migrations/migration.py", line 115, in apply
     operation.database_forwards(self.app_label, schema_editor, old_state,
 project_state)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/db/migrations/operations/fields.py", line 201, in
 database_forwards
     schema_editor.alter_field(from_model, from_field, to_field)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/db/backends/base/schema.py", line 484, in alter_field
     old_db_params, new_db_params, strict)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/db/backends/base/schema.py", line 566, in _alter_field
     old_default = self.effective_default(old_field)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/db/backends/base/schema.py", line 211, in
 effective_default
     default = field.get_db_prep_save(default, self.connection)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/db/models/fields/__init__.py", line 1627, in
 get_db_prep_save
     self.max_digits, self.decimal_places)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/db/backends/base/operations.py", line 477, in
 value_to_db_decimal
     return utils.format_number(value, max_digits, decimal_places)
   File "/new-django-project/.venv/lib/python3.4/site-
 packages/django/db/backends/utils.py", line 200, in format_number
     value = value.quantize(decimal.Decimal(".1") ** decimal_places,
 context=context)
 decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
 }}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25417#comment:5>
Django <https://code.djangoproject.com/>
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/064.00e1438f0625f242c838f9ac5c9260c2%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to