Django非托管只读数据库get查询失败问题求助
问题
尝试使用Django ORM操作一个只读数据库,所用模型如下:
class Languages(models.Model): idlanguage = models.IntegerField(primary_key=True) language = models.CharField(max_length=50) code = models.CharField(max_length=50) class Meta: managed = False db_table = 'languages'
settings.py中的数据库配置如下:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'XXXXXXX', 'USER': 'XXX', 'PASSWORD': 'XXXXXXXXXXXXXXXXXXXXX', 'HOST': '', 'PORT': '', }, 'ro_bdd': { 'ENGINE': 'django.db.backends.oracle', 'NAME': 'XXXXX', 'USER': 'XXXXXXXXXX', 'PASSWORD': 'XXXXX', 'HOST': 'XXXXXXXXX', 'PORT': 'XXXX', } }
执行查询时,Languages.objects.all().using("ro_bdd")和Languages.objects.filter(idlanguage=1).using("ro_bdd")均能正常返回结果,但执行Languages.objects.get(idlanguage=1).using("ro_bdd")时出现ProgrammingError,提示“relation « languages » does not exist”,生成的SQL语句为SELECT "languages"."idlanguage", "languages"."language", "languages"."code" FROM "languages" WHERE "languages"."idlanguage" = %s LIMIT 21,参数为(1,),请问为何get查询无法正常工作?
分析与解决
问题出在方法调用顺序错误:
get()方法会立即触发数据库查询,你先调用get(idlanguage=1)再调用using("ro_bdd")时,查询已经默认走了PostgreSQL数据库(default配置),但这个库中不存在languages表,所以抛出“relation « languages » does not exist”错误。- 而
all()和filter()返回的是惰性求值的QuerySet对象,调用using()会修改QuerySet绑定的数据库,直到实际遍历结果时才会触发查询,所以这两个方法的调用顺序能正常工作。
正确的写法应该把using()放在get()之前:
Languages.objects.using("ro_bdd").get(idlanguage=1)
这样ORM会先指定使用ro_bdd这个Oracle数据库,再执行get查询,就能正确找到对应的表并返回结果。
内容的提问来源于stack exchange,提问作者Aurélien
相关产品推荐
相关产品推荐

