这个错误:
(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
或者漏掉了。