Django ORM Filter无法匹配MySQL深层数据行,求排查问题
title字段缺少索引
5000条数据虽不算海量,但无索引会导致MySQL全表扫描,极端情况下可能因查询优化器选择的扫描策略遗漏数据。执行ALTER TABLE names ADD INDEX idx_title (title);给title字段添加索引,再测试查询。字符编码/大小写不匹配
检查数据库表的title字段编码(比如是否为utf8mb4)与Django配置的DATABASES中OPTIONS的charset是否一致;同时确认查询的keyName与数据库中存储的title是否存在大小写差异——MySQL默认在某些编码下(如utf8_general_ci)大小写不敏感,但如果是utf8_bin则严格区分,可尝试用filter(title__iexact=keyName)做不区分大小写查询测试。数据存在不可见字符或格式差异
部分深层数据的title可能包含空格、换行、制表符或其他不可见字符,肉眼无法区分。可在数据库中执行SELECT HEX(title) FROM names WHERE id = [深层数据ID];,对比查询用的keyName的十六进制值,确认是否一致;若存在差异,需清洗数据中的特殊字符。数据未提交事务
如果深层数据是通过批量插入或其他事务操作写入的,若事务未提交,程序无法读取到未提交的数据。检查数据插入逻辑,确认事务是否正常提交;也可直接在数据库客户端执行SELECT * FROM names WHERE title = 'xxx';,看是否能查到深层数据,排除程序层面的问题。异步查询实现错误
Django的异步查询需使用异步方法,若你只是把视图改成async但仍调用同步的first(),实际上还是同步查询,不会解决问题。正确的异步查询写法是:async def your_view(request): keyName = request.GET.get('key') result = await Names.objects.filter(title=keyName).afirst() # 后续逻辑Django或数据库缓存干扰
若开启了数据库查询缓存或Django的缓存框架,可能缓存了旧的查询结果。可尝试清除Django缓存(python manage.py clearcache),或在查询时添加no_cache(),比如Names.objects.filter(title=keyName).no_cache().first(),排除缓存影响。
内容的提问来源于stack exchange,提问作者reza.arghand

