#22741: Migrate fails with `TypeError` when using a callable default for a
`ForeignKey`
-------------------------------------+-------------------------------------
     Reporter:  rednaw               |                    Owner:  nobody
         Type:  Bug                  |                   Status:  closed
    Component:  Database layer       |                  Version:  master
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:  needsinfo
     Keywords:  migrations           |             Triage Stage:
  foreignkey                         |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by reinout):

 I'm seeing something that looks like the same issue. I *do* have a
 traceback :-) It is django 1.8.14 (I'm updating an ancient project):

 {{{
 Traceback (most recent call last):
   File "bin/test", line 42, in <module>
     sys.exit(djangorecipe.binscripts.test('trs.testsettings', '', 'trs'))
   File
 "/code/eggs/djangorecipe-2.2.1-py3.5.egg/djangorecipe/binscripts.py", line
 22, in test
     management.execute_from_command_line(sys.argv)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/core/management/__init__.py",
 line 354, in execute_from_command_line
     utility.execute()
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/core/management/__init__.py",
 line 346, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/core/management/commands/test.py",
 line 30, in run_from_argv
     super(Command, self).run_from_argv(argv)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/core/management/base.py", line
 394, in run_from_argv
     self.execute(*args, **cmd_options)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/core/management/commands/test.py",
 line 74, in execute
     super(Command, self).execute(*args, **options)
   File
 "/code/eggs/raven-5.7.2-py3.5.egg/raven/contrib/django/management/__init__.py",
 line 41, in new_execute
     return original_func(self, *args, **kwargs)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/core/management/base.py", line
 445, in execute
     output = self.handle(*args, **options)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/core/management/commands/test.py",
 line 90, in handle
     failures = test_runner.run_tests(test_labels)
   File "/code/eggs/django_nose-1.4.4-py3.5.egg/django_nose/runner.py",
 line 303, in run_tests
     result = self.run_suite(nose_argv)
   File "/code/eggs/django_nose-1.4.4-py3.5.egg/django_nose/runner.py",
 line 241, in run_suite
     addplugins=plugins_to_add)
   File "/code/eggs/nose-1.3.7-py3.5.egg/nose/core.py", line 121, in
 __init__
     **extra_args)
   File "/usr/lib/python3.5/unittest/main.py", line 94, in __init__
     self.runTests()
   File "/code/eggs/nose-1.3.7-py3.5.egg/nose/core.py", line 207, in
 runTests
     result = self.testRunner.run(self.test)
   File "/code/eggs/nose-1.3.7-py3.5.egg/nose/core.py", line 50, in run
     wrapper = self.config.plugins.prepareTest(test)
   File "/code/eggs/nose-1.3.7-py3.5.egg/nose/plugins/manager.py", line 99,
 in __call__
     return self.call(*arg, **kw)
   File "/code/eggs/nose-1.3.7-py3.5.egg/nose/plugins/manager.py", line
 167, in simple
     result = meth(*arg, **kw)
   File "/code/eggs/django_nose-1.4.4-py3.5.egg/django_nose/plugin.py",
 line 82, in prepareTest
     self.old_names = self.runner.setup_databases()
   File "/code/eggs/django_nose-1.4.4-py3.5.egg/django_nose/runner.py",
 line 490, in setup_databases
     return super(NoseTestSuiteRunner, self).setup_databases()
   File "/code/eggs/Django-1.8.14-py3.5.egg/django/test/runner.py", line
 166, in setup_databases
     **kwargs
   File "/code/eggs/Django-1.8.14-py3.5.egg/django/test/runner.py", line
 370, in setup_databases
     serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE",
 True),
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/backends/base/creation.py",
 line 368, in create_test_db
     test_flush=not keepdb,
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/core/management/__init__.py",
 line 120, in call_command
     return command.execute(*args, **defaults)
   File
 "/code/eggs/raven-5.7.2-py3.5.egg/raven/contrib/django/management/__init__.py",
 line 41, in new_execute
     return original_func(self, *args, **kwargs)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/core/management/base.py", line
 445, in execute
     output = self.handle(*args, **options)
   File
 
"/code/eggs/Django-1.8.14-py3.5.egg/django/core/management/commands/migrate.py",
 line 222, in handle
     executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/migrations/executor.py",
 line 110, in migrate
     self.apply_migration(states[migration], migration, fake=fake,
 fake_initial=fake_initial)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/migrations/executor.py",
 line 148, in apply_migration
     state = migration.apply(state, schema_editor)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/migrations/migration.py",
 line 115, in apply
     operation.database_forwards(self.app_label, schema_editor, old_state,
 project_state)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/migrations/operations/fields.py",
 line 62, in database_forwards
     field,
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/backends/sqlite3/schema.py",
 line 179, in add_field
     self._remake_table(model, create_fields=[field])
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/backends/sqlite3/schema.py",
 line 77, in _remake_table
     self.effective_default(field)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/backends/base/schema.py",
 line 211, in effective_default
     default = field.get_db_prep_save(default, self.connection)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/models/fields/related.py",
 line 1958, in get_db_prep_save
     return self.related_field.get_db_prep_save(value,
 connection=connection)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/models/fields/__init__.py",
 line 710, in get_db_prep_save
     prepared=False)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/models/fields/__init__.py",
 line 977, in get_db_prep_value
     value = self.get_prep_value(value)
   File
 "/code/eggs/Django-1.8.14-py3.5.egg/django/db/models/fields/__init__.py",
 line 985, in get_prep_value
     return int(value)
 TypeError: int() argument must be a string, a bytes-like object or a
 number, not 'YearWeek'
 }}}

 The relevant field on my model looks like this:

 {{{
     start = models.ForeignKey(
         'YearWeek',
         blank=True,
         null=True,
         default=this_year_week,
         related_name="starting_projects",
         verbose_name="startweek")
 }}}

 So... a callable as a default that returns an object instance (of the
 correct type), but it looks like the migration mechanism wants a foreign
 key ID instead of an actual instance.

 Two possible things that might make it a corner case:

 - I see the error when I run my tests. It happens in the test setup. The
 complication/cornercase is that the callable tries to grab the instance
 from memcache. So the test might get an instance somehow without it
 actually having an ID in the database. Doesn't sound very logical, I'm
 just mentioning it :-)

 - It is an initial migration.

 I haven't investigated further. I also don't know yet if the issue should
 be re-openend. I'm leaving it closed for now and I'll do some further
 digging.

--
Ticket URL: <https://code.djangoproject.com/ticket/22741#comment:3>
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.6c50111d2df548bc2bc2d681fc0adce8%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to