欢迎来到海上华帆的博客园子

记录一些学习过程中的心得体会,供自己和有缘人参考!

Django数据库迁移 需填充默认值 选择输入默认值后发现所输入的默认值与数据类型不符 的解决方法

除了删除数据库和迁移文件(只删除数据库还是会报错的,如下实例就是如此),还有更简单的方法可以解决这个问题。

后台报错信息:

➜  baking_wms git:(v22/multi-accounting-isolation) ✗ rm db.sqlite3
rm: db.sqlite3: No such file or directory
➜  baking_wms git:(v22/multi-accounting-isolation) ✗ python manage.py migrate
Operations to perform:
  Apply all migrations: accounts, admin, auth, contenttypes, core, cost, delivery, equipment, inventory, material, procurement, production, quality, recipe, sales, sessions, store
Running migrations:
  Applying core.0002_companytype_alter_company_company_type...Traceback (most recent call last):
  File "/Users/liuyuhua/trae/wms/baking_wms/manage.py", line 22, in <module>
    main()
  File "/Users/liuyuhua/trae/wms/baking_wms/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/Users/liuyuhua/trae/wms/baking_wms/venv/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/Users/liuyuhua/trae/wms/baking_wms/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 "/Users/liuyuhua/trae/wms/baking_wms/venv/lib/python3.11/site-packages/django/core/management/base.py", line 416, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/liuyuhua/trae/wms/baking_wms/venv/lib/python3.11/site-packages/django/core/management/base.py", line 460, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/liuyuhua/trae/wms/baking_wms/venv/lib/python3.11/site-packages/django/core/management/base.py", line 107, in wrapper
    res = handle_func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/liuyuhua/trae/wms/baking_wms/venv/lib/python3.11/site-packages/django/core/management/commands/migrate.py", line 353, in handle
    post_migrate_state = executor.migrate(
                         ^^^^^^^^^^^^^^^^^
  File "/Users/liuyuhua/trae/wms/baking_wms/venv/lib/python3.11/site-packages/django/db/migrations/executor.py", line 135, in migrate
    state = self._migrate_all_forwards(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/liuyuhua/trae/wms/baking_wms/venv/lib/python3.11/site-packages/django/db/migrations/executor.py", line 167, in _migrate_all_forwards
    state = self.apply_migration(
            ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/liuyuhua/trae/wms/baking_wms/venv/lib/python3.11/site-packages/django/db/migrations/executor.py", line 252, in apply_migration
    with self.connection.schema_editor(
  File "/Users/liuyuhua/trae/wms/baking_wms/venv/lib/python3.11/site-packages/django/db/backends/sqlite3/schema.py", line 39, in __exit__
    self.connection.check_constraints()
  File "/Users/liuyuhua/trae/wms/baking_wms/venv/lib/python3.11/site-packages/django/db/backends/sqlite3/base.py", line 304, in check_constraints
    raise IntegrityError(
django.db.utils.IntegrityError: The row in table 'core_company' with primary key '1' has an invalid foreign key: core_company.company_type_id contains a value 'padena' that does not have a corresponding value in core_companytype.id.

几种解决方案:

方案1:修改迁移文件(推荐)

首先查看当前的迁移文件,然后修改它:

Read file: core/migrations/0002_companytype_alter_company_company_type.py
现在我来修改这个迁移文件,添加数据迁移步骤:

现在删除之前创建的数据迁移文件,因为我们已经在主迁移文件中处理了:

Ran tool
现在运行迁移:

python manage.py migrate

需要修复inventory迁移文件的依赖关系:

Read file: inventory/migrations/0004_warehouse_company.py
现在再次运行迁移:

python manage.py migrate

上面的报错(TypeError: Tried to update field core.Company.company_type with a model instance... Use a value compatible with CharField.)是因为在迁移过程中,company_type字段由CharField变成了ForeignKey,而直接赋值了model实例,Django 迁移系统在此阶段还没完成字段类型的转换。

更简单的处理方法:

方案一:手动修正数据

  1. 进入数据库(如sqlite3 db_hq.sqlite3)。
  2. 将core_company表中company_type字段的值全部改为对应CompanyType的主键(id),而不是字符串(如'padena')。
    • 你可以先查CompanyType表,记下各类型的id。
    • 然后update core_company set company_type=1 where company_type='padena'; 依次处理所有类型。
  3. 重新运行迁移

方案二:在迁移前先清空或修正company_type字段

  • 可以在迁移前,先将core_company表的company_type字段全部置为NULL或空字符串,然后再迁移。
  • 迁移后再手动在后台补全公司类型。

方案三:在迁移文件中用原始SQL赋值

  • 在迁移文件的RunPython步骤中,使用cursor.execute写原始SQL,将字符串类型的company_type批量替换为新表的id。

总结:
不需要删库,只需在迁移前用SQL把company_type字段的内容批量替换为新表的主键id,或者先置空,迁移后再补全即可。
这样可以安全、快速地解决迁移报错,无需重建所有数据。

posted @ 2025-06-22 08:52  海上华帆  阅读(16)  评论(0)    收藏  举报