django外键字段会自动在数据库字段后面加上_id

这个错误:

复制代码
(1054, "Unknown column 'wms_inventory_check_task.plan_id' in 'where clause'")

表示:

Django 查询 wms_inventory_check_task 表时,SQL 使用了 plan_id 字段,但是你的 MySQL 表中不存在 plan_id 这个列。


1. 产生原因

你的 Django Model:

python 复制代码
plan = models.ForeignKey(
    InventoryCheckPlan,
    on_delete=models.CASCADE,
    related_name='tasks',
)

Django 会默认生成数据库字段:

sql 复制代码
plan_id BIGINT

所以 ORM 查询:

python 复制代码
InventoryCheckTask.objects.filter(
    plan_id=1
)

实际 SQL:

sql 复制代码
SELECT *
FROM wms_inventory_check_task
WHERE plan_id = 1;

但是你的数据库表:

sql 复制代码
SHOW COLUMNS FROM wms_inventory_check_task;

可能没有:

复制代码
plan_id

2. 检查数据库表

执行:

sql 复制代码
DESC wms_inventory_check_task;

正常应该看到:

复制代码
+--------------+------------+
| Field        | Type       |
+--------------+------------+
| id           | bigint     |
| plan_id      | bigint     |
| location_id  | int        |
| assignee_id  | bigint     |
| status       | smallint   |
+--------------+------------+

如果没有 plan_id,就是数据库和 Model 不一致。


3. 解决方式一(推荐):执行 migration

查看 migration:

bash 复制代码
python manage.py makemigrations

然后:

bash 复制代码
python manage.py migrate

Django 会创建:

sql 复制代码
ALTER TABLE wms_inventory_check_task
ADD COLUMN plan_id BIGINT NOT NULL;

4. 解决方式二:数据库已经手动创建

如果你之前是手写 SQL 创建表:

例如:

sql 复制代码
CREATE TABLE wms_inventory_check_task(
    id BIGINT,
    plan BIGINT
);

错误。

应该是:

sql 复制代码
plan_id BIGINT NOT NULL

因为 Django ForeignKey:

python 复制代码
plan = models.ForeignKey(...)

数据库字段不是:

复制代码
plan

而是:

复制代码
plan_id

5. 如果字段实际叫 plan

比如你的表:

sql 复制代码
CREATE TABLE wms_inventory_check_task(
    id BIGINT,
    plan BIGINT
)

可以告诉 Django:

python 复制代码
plan = models.ForeignKey(
    InventoryCheckPlan,
    db_column='plan',
    on_delete=models.CASCADE
)

这样 Django 查询:

sql 复制代码
WHERE plan = 1

而不是:

sql 复制代码
WHERE plan_id = 1

但是一般不推荐,因为 Django 规范就是:

复制代码
xxx_id

6. 如果 migration 状态混乱

查看:

bash 复制代码
python manage.py showmigrations

例如:

复制代码
[X] 0001_initial
[X] 0002_add_task

显示已经执行,但是数据库没有字段。

说明:

migration 记录存在,但是数据库结构不一致。

可以:

开发环境

bash 复制代码
python manage.py migrate app_name zero
python manage.py migrate

生产环境

不要回滚,手动补字段:

sql 复制代码
ALTER TABLE wms_inventory_check_task
ADD COLUMN plan_id BIGINT NOT NULL;

然后补外键:

sql 复制代码
ALTER TABLE wms_inventory_check_task
ADD CONSTRAINT fk_task_plan
FOREIGN KEY(plan_id)
REFERENCES wms_inventory_check_plan(id);

结合你前面的 Model

你的表应该至少包含:

sql 复制代码
id
plan_id
location_id
assignee_id
status

现在错误说明:

text 复制代码
plan_id 缺失

所以第一步直接执行:

sql 复制代码
DESC wms_inventory_check_task;

看一下字段。

大概率是你之前手动建表时把:

sql 复制代码
plan_id

写成了:

sql 复制代码
plan

或者漏掉了。

相关推荐
<小智>1 天前
及时做APP开发实战(十二)-LazyForEach懒加载优化实践
数据库·鸿蒙
龙仔7251 天前
人大金仓KingbaseES V8 手动单库备份&恢复操作笔记
数据库·笔记·oracle·人大金仓
梅雅达编程笔记1 天前
零基础学 Python 第14章 | 模块、包与第三方库
开发语言·python·django·numpy·pandas
夏贰四1 天前
数据库迁移怎样降低人力投入?数据库迁移怎么实现全量增量同步?
数据库·数据库迁移
梅雅达编程笔记1 天前
零基础学 Python 第15章 | 类与对象:面向对象编程入门
开发语言·python·django·numpy·pandas
汇智信科1 天前
图谱、向量、关键词、SQL多路一体,FastKG垂域召回率100%拉满
网络·数据库·ai编程·汇智信科·hsim·fastclaw·汇智龙虾
笨蛋不要掉眼泪1 天前
MySQL架构揭秘:慢查询日志详解
数据库·mysql·架构
pulinzt1 天前
Tableau的基础使用
数据库·numpy
糖果店的幽灵1 天前
【langgraph 从入门到精通graphApi 篇】LangGraphAPI 方式调用 - 初识与核心概念
数据库·人工智能·langgraph