使用Djongo关联MongoDB时Django外键操作报错求助
Django + Djongo 外键录入数据时SQL参数解析错误排查方案
问题描述
在Django中定义了两个模型Test_DB和ForeignKey_Test,后者包含指向前者的外键字段。通过Django默认管理面板录入数据时,触发Djongo错误:
The above exception ( Keyword: FAILED SQL: SELECT %(0)s AS "a" FROM "testapp_test_db" WHERE "testapp_test_db"."id" = %(1)s LIMIT 1 Params: (1, 1) Version: 1.3.6 Sub SQL: None FAILED SQL: None Params: None Version: None) was the direct cause of the following exception:
推测是Djongo解析SQL时参数匹配异常导致。
模型代码:
class Test_DB(models.Model): name = models.CharField(max_length=50) class ForeignKey_Test(models.Model): name = models.CharField(max_length=50) test_id = models.ForeignKey(to='Test_DB', on_delete=models.CASCADE)
核心依赖版本:
- Django==4.1.1
- djongo==1.3.6
- pymongo==3.12.3
原因分析与解决办法
1. 版本兼容性问题
Djongo 1.3.6发布时间早于Django 4.1.1,对Django 4.x版本的ORM查询语法支持不完善,导致外键查询时参数解析出错。
解决步骤:
- 升级Djongo到兼容Django 4.1的版本,推荐
djongo==1.3.8或更高版本,同时同步升级pymongo到4.0+版本:
pip install --upgrade djongo pymongo
2. 外键字段命名冲突
外键字段命名为test_id,与MongoDB原生的_id字段命名规则冲突,Djongo在转换查询时出现参数映射错误。
解决步骤:
- 修改外键字段名,避免以
_id结尾,比如改为test_db:
class ForeignKey_Test(models.Model): name = models.CharField(max_length=50) test_db = models.ForeignKey(to='Test_DB', on_delete=models.CASCADE)
- 执行迁移更新数据库结构:
python manage.py makemigrations python manage.py migrate
3. Djongo模板解析BUG
错误信息显示SQL模板使用了位置参数%(0)s和%(1)s,但实际传入的参数元组无法匹配,属于Djongo的内部解析BUG。
临时修复方案:
- 为外键字段指定
db_column属性,明确映射到MongoDB的字段名:
class ForeignKey_Test(models.Model): name = models.CharField(max_length=50) test_id = models.ForeignKey( to='Test_DB', on_delete=models.CASCADE, db_column='test_db_ref' )
- 重新执行迁移后,再次尝试在admin面板录入数据。
验证流程
- 应用上述任一方案后,重启Django服务
- 先在admin中创建一条
Test_DB数据 - 再创建
ForeignKey_Test数据,关联已创建的Test_DB条目,提交后确认是否报错
内容的提问来源于stack exchange,提问作者Shashank Shekhar
相关产品推荐
相关产品推荐

