升级Django和Python版本时,FloatField的默认值设置为string时出现问题

升级Django和Python版本时,FloatField的默认值设置为string时出现问题,python,django,postgresql,django-models,Python,Django,Postgresql,Django Models,在使用Django 1.8和Python 2.7的模型中,我们进行了一次迁移,意外地将FloatField的默认值设置为空字符串(默认值=“”),Django似乎将其解释为字节字符串: class Migration(migrations.Migration): dependencies = [ ('reo', '0030_merge'), ] operations = [ migrations.CreateModel(

在使用Django 1.8和Python 2.7的模型中,我们进行了一次迁移,意外地将FloatField的默认值设置为空字符串(默认值=“”),Django似乎将其解释为字节字符串:

class Migration(migrations.Migration):

    dependencies = [
        ('reo', '0030_merge'),
    ]

    operations = [
        migrations.CreateModel(
            name='ProfileModel',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('pre_setup_scenario_seconds', models.FloatField(default=b'', null=True)),
            ],
        ),
    ]

升级到Django 2.2和Python 3.6后,Django使用
manage.py migrate
发出警告,指出存在未迁移的更改。将默认值从
''
更改为
None
并运行
manage.py makemigrations
后,我们得到:

operations = [
        migrations.AlterField(
            model_name='profilemodel',
            name='pre_setup_scenario_seconds',
            field=models.FloatField(default=None, null=True),
        ),
]
然后运行
manage.py migrate
生成:

nlaws-> python manage.py migrate
Operations to perform:
  Apply all migrations: auth, contenttypes, django_celery_results, proforma, reo, resilience_stats, sessions, summary, tastypie
Running migrations:
  Applying reo.0050_auto_20191030_1738...Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/core/management/base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/core/management/base.py", line 364, in execute
    output = self.handle(*args, **options)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/core/management/base.py", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 234, in handle
    fake_initial=fake_initial,
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/migrations/executor.py", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/migrations/executor.py", line 245, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/migrations/migration.py", line 124, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/migrations/operations/fields.py", line 249, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 535, in alter_field
    old_db_params, new_db_params, strict)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/backends/postgresql/schema.py", line 124, in _alter_field
    new_db_params, strict,
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 648, in _alter_field
    old_default = self.effective_default(old_field)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 233, in effective_default
    return field.get_db_prep_save(self._effective_default(field), self.connection)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 789, in get_db_prep_save
    return self.get_db_prep_value(value, connection=connection, prepared=False)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 784, in get_db_prep_value
    value = self.get_prep_value(value)
  File "/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1739, in get_prep_value
    return float(value)
ValueError: could not convert string to float: 
nlaws->python manage.py迁移
要执行的操作:
应用所有迁移:auth、contenttypes、django_Cellery_结果、形式表、reo、恢复力_统计、会话、摘要、tastypie
运行迁移:
正在应用reo.0050_auto_20191030_1738…回溯(最近一次呼叫最后一次):
文件“manage.py”,第10行,在
从命令行(sys.argv)执行命令
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/core/management/_init__.py”,第381行,从命令行执行
utility.execute()
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/core/management/_init__.py”,执行中第375行
self.fetch_命令(子命令)。从_argv(self.argv)运行_
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/core/management/base.py”,第323行,在运行时从
self.execute(*args,**cmd_选项)
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/core/management/base.py”,第364行,在execute中
输出=self.handle(*args,**选项)
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site-packages/django/core/management/base.py”,第83行,包装
res=句柄函数(*args,**kwargs)
handle中的文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/core/management/commands/migrate.py”,第234行
假首字母=假首字母,
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/migrations/executor.py”,migrate中的第117行
状态=self.\u迁移\u所有\u转发(状态,计划,完整计划,假=假,假首字母=假首字母)
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/migrations/executor.py”,第147行,全部向前迁移
state=self.apply\u迁移(state,migration,false=false,false\u initial=false\u initial)
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/migrations/executor.py”,第245行,在apply_migration中
state=migration.apply(状态,模式编辑器)
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/migrations/migration.py”,应用中的第124行
操作。数据库转发(self.app\u标签、模式编辑器、旧状态、项目状态)
数据库中的文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/migrations/operations/fields.py”,第249行
schema_editor.alter_字段(从_模型、从_字段到_字段)
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/backends/base/schema.py”,第535行,在alter_字段中
旧参数,新参数,严格)
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/backends/postgresql/schema.py”,第124行,在_alter_字段中
新的参数,严格的,
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/backends/base/schema.py”,第648行,在\u alter\u字段中
旧默认值=自生效默认值(旧字段)
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/backends/base/schema.py”,第233行,默认有效
返回字段.get\u db\u prep\u save(self.\u effective\u default(字段),self.connection)
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/models/fields/_________.py”,第789行,在get_db_prep_save中
返回self.get_db_prep_值(值,connection=connection,prepared=False)
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/models/fields/_init__.py”,第784行,在get_db_prep_值中
value=self.get\u prep\u值(value)
文件“/Users/nlaws/.virtualenv/api/lib/python3.6/site packages/django/db/models/fields/_init__.py”,第1739行,在get_prep_值中
返回浮动(值)
ValueError:无法将字符串转换为浮点:
有人知道如何解决这个问题吗

它似乎与一个字符串值设置为二进制字段的默认值有关,并且似乎是Django源代码中的一个错误。

来自的建议有助于解决此问题,特别是我们最终:

  • 创建新的浮点字段2
  • 运行管理命令从一个字段获取数据,将其转换为浮点,然后将其保存到另一个字段
  • 删除第一个(字符串)字段
  • 将第二个字段(float字段)重命名为您需要的任何名称
  • 步骤2是通过
    迁移完成的

    UPDATE reo_profilemodel SET pre_setup_scenario_seconds2 = cast(pre_setup_scenario_seconds as double precision)