django操作mysql常见错误大全

因为我的机器使用的是mysql容器,所以可以打印环境环境获取登录账密

bash 复制代码
docker exec -it db printenv | grep MYSQL

下面用「Django + MySQL」的视角,把 开发/上线 99% 会踩的 MySQL 典型错误 汇总成一张"踩坑地图"。

每个错误都给出:

  1. 异常堆栈(Django 真实报错)
  2. 根因一句话
  3. 复现代码(最小 Django 示例)
  4. 修复方案(含 ORM 写法或配置)

复制即可复现,跟着敲一遍,以后看到同样日志秒定位。


0. 环境统一

  • Django 4.2 + mysqlclient 2.2 + MySQL 8.0
  • 默认配置(不改 SQL_MODE)以便暴露问题
python 复制代码
# settings.py
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": "django_err",
        "USER": "root",
        "PASSWORD": "password",
        "HOST": "127.0.0.1",
        "PORT": "3306",
        "OPTIONS": {"init_command": "SET sql_mode='STRICT_TRANS_TABLES'"},  # 严格模式先打开
    }
}

1. Duplicate entry ------ 主键/唯一键冲突

异常

django 复制代码
django.db.utils.IntegrityError: (1062, "Duplicate entry 'tom' for key 'users.username'")

复现

python 复制代码
class User(models.Model):
    username = models.CharField(max_length=50, unique=True)

User.objects.create(username="tom")
User.objects.create(username="tom")  # 再敲一次

修复

python 复制代码
# 代码层先查后插 或 数据库层 on conflict
user, created = User.objects.get_or_create(username="tom")

2. Data too long ------ 列长度超限

异常

django 复制代码
django.db.utils.DataError: (1406, "Data too long for column 'title' at row 1")

复现

python 复制代码
class Article(models.Model):
    title = models.CharField(max_length=10)

Article.objects.create(title="12345678901")  # 11 个字符

修复

python 复制代码
# 要么改模型
title = models.CharField(max_length=255)
# 要么截断
Article.objects.create(title=long_title[:10])

3. DoesNotExist ------ 查询为空抛异常

异常

django 复制代码
django.core.exceptions.ObjectDoesNotExist: User matching query does not exist.

复现

python 复制代码
user = User.objects.get(pk=999)  # 没有这条记录

修复

python 复制代码
# 用 filter + first 或 get_object_or_404
user = User.objects.filter(pk=999).first()  # 返回 None
from django.shortcuts import get_object_or_404
user = get_object_or_404(User, pk=999)

4. Field cannot be null ------ 非空约束

异常

django 复制代码
django.db.utils.IntegrityError: (1048, "Column 'email' cannot be null")

复现

python 复制代码
class User(models.Model):
    email = models.EmailField()  # 默认 blank=False, null=False

User.objects.create(username="tom")  # 没给 email

修复

python 复制代码
# 1. 允许空
email = models.EmailField(blank=True, null=True)
# 2. 给默认值
email = models.EmailField(default="")
# 3. 代码里传值
User.objects.create(username="tom", email="tom@example.com")

5. Incorrect string value ------ 表情符/生僻字乱码

异常

django 复制代码
django.db.utils.OperationalError: (1366, "Incorrect string value: '\\xF0\\x9F\\x98\\x80...' for column 'nickname'")

复现

python 复制代码
User.objects.create(nickname="😀")  # utf8mb3 存不进 emoji

修复

  1. 数据库/表/列字符集改成 utf8mb4
sql 复制代码
ALTER DATABASE django_err CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  1. 连接层也指定:
python 复制代码
"OPTIONS": {"charset": "utf8mb4"},

再插入 emoji 就正常了。


6. Lost connection ------ 长查询被 kill

异常

django 复制代码
django.db.utils.OperationalError: (2013, 'Lost connection to MySQL server during query')

复现

python 复制代码
# 故意搞个大表全表扫 + 不睡觉
User.objects.all().select_related("profile")[0:100000]  # 100 万次 join

修复

  • 优化 SQL(加索引、分页、只取所需列)
  • 调大 wait_timeout / interactive_timeout(治标不治本)
  • iterator() 分批拉:
python 复制代码
for user in User.objects.all().iterator(chunk_size=2000):
    ...

7. Too many connections ------ 连接打满

异常

django 复制代码
django.db.utils.OperationalError: (1040, 'Too many connections')

复现

并发压测 ab -n 10000 -c 200 ... 超过 max_connections=151 即可。

修复

  1. 数据库层:温和涨上限
sql 复制代码
SET GLOBAL max_connections = 300;
  1. 应用层:用连接池 + 合理并发
python 复制代码
# settings.py 里加
DATABASES["default"]["CONN_MAX_AGE"] = 600  # 复用连接
  1. 代码里别泄露连接(长时间不 close)

8. Deadlock found ------ 并发死锁

异常

django 复制代码
django.db.utils.OperationalError: (1213, 'Deadlock found when trying to get lock; try restarting transaction')

复现

python 复制代码
# 两个 view 同时
@transaction.atomic
def debit(request):
    a = Account.objects.select_for_update().get(id=1)
    b = Account.objects.select_for_update().get(id=2)
    ...

# 另一个线程反向顺序
@transaction.atomic
def debit2(request):
    b = Account.objects.select_for_update().get(id=2)  # 先 2
    a = Account.objects.select_for_update().get(id=1)  # 后 1

交叉拿锁 → 死锁。

修复

  • 固定加锁顺序(总是 1→2)
  • 精简事务范围,尽快提交
  • 捕获重试(Django 3.2+ 自动重试 max_retries=3

9. IntegrityError ------ 外键级联失败

异常

django 复制代码
django.db.utils.IntegrityError: (1452, 'Cannot add or update a child row: a foreign key constraint fails ...)

复现

python 复制代码
class Order(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)

Order.objects.create(user_id=9999)  # 不存在 user 9999

修复

python 复制代码
# 保证外键值存在
user = User.objects.get(pk=user_id)
Order.objects.create(user=user)

10. ProgrammingError ------ 拼错 raw SQL

异常

django 复制代码
django.db.utils.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual ...")

复现

python 复制代码
from django.db import connection
with connection.cursor() as c:
    c.execute("SELCT * FROM users WHERE id = %s", [1])  # SELCT 拼错

修复

  • 用 ORM 先顶一波,必须 raw 时开 sql_mode=STRICT 并打印语句再执行。

一键速查表(打印贴墙)

错误码 Django 异常 典型场景 最快修复
1062 IntegrityError 唯一键冲突 get_or_create
1406 DataError 列太长 加长/截断
1048 IntegrityError 非空未给 设默认值
1366 OperationalError emoji 乱码 utf8mb4
2013 OperationalError 长查询 索引+分页
1040 OperationalError 连接打满 连接池+涨上限
1213 OperationalError 死锁 固定顺序+重试

结语

把上面 10 个案例挨个 python manage.py shell 跑一遍,再遇到一样日志就能秒定位。

建议收藏 + 星标,下次面试/上线/救火,直接翻表。

相关推荐
liuxiaowei36 小时前
【绝版教程】新版MySQL DBA高级实战进阶班 MySQL8.0 姜承尧-腾讯数据库总监
数据库·mysql·dba
sg_knight9 小时前
MySQL 存储过程详解:从入门到实战
android·数据库·mysql·database·dba·关系型数据库·db
Database_Cool_10 小时前
企业级多模态分析计算引擎选型:首选 AnalyticDB MySQL 向量 + SQL + 实时一体化方案
数据库·sql·mysql
宇宙第一小趴菜12 小时前
五、Oracle vs MySQL 架构深度对比笔记
mysql·oracle·架构
weixin_BYSJ198713 小时前
「课设设计」springboot校园超市助购系统26449 (附源码)
java·javascript·spring boot·python·django·flask·php
Database_Cool_14 小时前
云数据仓库开通指南:阿里云 AnalyticDB MySQL 10 分钟从 0 到分析实战教程
数据仓库·mysql·阿里云
—Miss. Z—16 小时前
计算机二级MySQL——简单应用题(事件&视图)
android·mysql·adb
会编程的土豆17 小时前
MySQL 中的 IN 和 EXISTS(零基础笔记)
数据库·笔记·mysql
AAA@峥18 小时前
系统化学习 MySQL:数据类型、库表管理、增删改查全解析
数据库·学习·mysql
小白说大模型1 天前
Codex++安全边界探秘:从模型能力到安全防护的深度解析
java·数据库·人工智能·python·mysql·安全