Migration Woes: TypeError: int() argument must be a string... on ForeignKeys

74 views
Skip to first unread message

Matthew Pava

unread,
Sep 12, 2017, 5:10:52 PM9/12/17
to django...@googlegroups.com

I’m trying to alter my foreign keys on my audit log models to allow for null.  Django creates a new migration file, with an operation something like below:

 

        migrations.AlterField(

            model_name='checklistauditlogentry',

            name='usage',

            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='_auditlog_checklistusages', to='general.DisplayName'),

        )

 

Upon applying the migrations, I get this error (without full path shown):

TypeError: int() argument must be a string, a bytes-like object or a number, not 'DisplayName'

 

I just can’t seem to figure this one out.  I can’t just delete the migrations and start over because I really need Django to modify the database to remove the requirement on those fields.

 

Full trace:

Running migrations:

  Applying documents.0002_auto_20170912_1445...Traceback (most recent call last):

  File "manage.py", line 10, in <module>

    execute_from_command_line(sys.argv)

  File "\lib\site-packages\django\core\management\__init__.py", line 364, in execute_from_command_line

    utility.execute()

  File "\lib\site-packages\django\core\management\__init__.py", line 356, in execute

    self.fetch_command(subcommand).run_from_argv(self.argv)

  File "\lib\site-packages\django\core\management\base.py", line 283, in run_from_argv

    self.execute(*args, **cmd_options)

  File "\lib\site-packages\django\core\management\base.py", line 330, in execute

    output = self.handle(*args, **options)

  File "\lib\site-packages\django\core\management\commands\migrate.py", line 204, in handle

    fake_initial=fake_initial,

  File "\lib\site-packages\django\db\migrations\executor.py", line 115, in migrate

    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)

  File "\lib\site-packages\django\db\migrations\executor.py", line 145, in _migrate_all_forwards

    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)

  File "\lib\site-packages\django\db\migrations\executor.py", line 244, in apply_migration

    state = migration.apply(state, schema_editor)

  File "\lib\site-packages\django\db\migrations\migration.py", line 129, in apply

    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)

  File "\lib\site-packages\django\db\migrations\operations\fields.py", line 216, in database_forwards

    schema_editor.alter_field(from_model, from_field, to_field)

  File "\lib\site-packages\django\db\backends\base\schema.py", line 515, in alter_field

    old_db_params, new_db_params, strict)

  File "\lib\site-packages\django\db\backends\postgresql\schema.py", line 112, in _alter_field

    new_db_params, strict,

  File "\lib\site-packages\django\db\backends\base\schema.py", line 612, in _alter_field

    old_default = self.effective_default(old_field)

  File "\lib\site-packages\django\db\backends\base\schema.py", line 229, in effective_default

    default = field.get_db_prep_save(default, self.connection)

  File "\lib\site-packages\django\db\models\fields\related.py", line 963, in get_db_prep_save

    return self.target_field.get_db_prep_save(value, connection=connection)

  File "\lib\site-packages\django\db\models\fields\__init__.py", line 770, in get_db_prep_save

    prepared=False)

  File "\lib\site-packages\django\db\models\fields\__init__.py", line 958, in get_db_prep_value

    value = self.get_prep_value(value)

  File "\lib\site-packages\django\db\models\fields\__init__.py", line 966, in get_prep_value

    return int(value)

TypeError: int() argument must be a string, a bytes-like object or a number, not 'DisplayName'

Matthew Pava

unread,
Sep 13, 2017, 10:41:06 AM9/13/17
to django...@googlegroups.com

Okay, after much investigation, I found that the default value on this exact field was actually a callable that returned an instance of DisplayName rather than the pk.  After changing that, the migrations ran successfully.  I wonder if Django could provide a better hint of such issues.  It’s strange because that default was on the previous migration file in the AddField command, but the migrate command never threw an error.  It only threw it on AlterField, and the default didn’t even have to be specified in the AlterField version.

 

Thank you,

Matthew

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/ab2c2b14c7a04e82835dd53fc58eef30%40ISS1.ISS.LOCAL.
For more options, visit https://groups.google.com/d/optout.

Melvyn Sopacua

unread,
Sep 13, 2017, 11:14:02 AM9/13/17
to django...@googlegroups.com
The issue didn't crop up, because there were no rows when you added
the field, so default isn't called. If you had existing data, then it
would've triggered.

What default should return for foreign keys is actually documented:

> For fields like ForeignKey that map to model instances, defaults should be the value of the field they reference (pk unless to_field is set) instead of model instances.

https://docs.djangoproject.com/en/1.11/ref/models/fields/#default
> https://groups.google.com/d/msgid/django-users/9cfb3dab4545461ea8e0964ea1be6ebc%40ISS1.ISS.LOCAL.
>
> For more options, visit https://groups.google.com/d/optout.



--
Melvyn Sopacua
Reply all
Reply to author
Forward
0 new messages