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

或者漏掉了。

相关推荐
这个DBA有点耶3 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
DBA_G3 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库
自由能燃气设备3 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能
科创致远3 天前
科创致远 ESOP 系统核心效能与实战价值展示
大数据·数据库·人工智能·精益工程
kybs19913 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net
2601_962218613 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法
张洛闻Eren3 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
醇氧3 天前
Python`__pycache__` 被 Git 跟踪的排查与解决
python·django
于平安3 天前
MySQL-触发器
数据库·mysql
白远山3 天前
上海24小时自助健身房解决方案实战指南与经验分享
java·数据库·架构·需求分析