2016-11-07 31 views
2

我对使用django ORM的django子查询感到担忧。当我们获取查询集或执行数据库操作时,我可以选择绕过django可能为数据库所做的所有假设,通过强制使用我想要的特定数据库来使用数据库。为什么Django子查询使用的数据库不粘?

b_det = Book.objects.using('some_db').filter(book_name = 'Mark') 

以上无视任何数据库路由器,我可能已设置并直接进入'some_db'。

但如果我的模型大约看起来像这样: -

class Author(models.Model): 
    author_name=models.CharField(max_length=255) 
    author_address=models.CharField(max_length=255) 

class Book(models.Model): 
    book_name=models.CharField(max_length=255) 
    author=models.ForeignKey(Author, null = True) 

我取表示被称为马克像这样所有书籍查询集: -

b_det = Book.objects.using('some_db').filter(book_name = 'Mark') 

再后来,如果某处代码我触发子查询通过做这样的事情: -

if b_det: 
    auth_address = b_det[0].author.author_address 

然后这不会让你它是我早期为主查询指定的原始数据库'some_db'的一部分。这又通过路由器并拾取(可能)不正确的数据库。

为什么Django会这样做。恕我直言,如果我选择了原始查询的数据库强制使用,那么即使是子查询也需要使用同一个数据库。数据库路由器为什么必须为此而出现?

回答

0

这不是严格的SQL意义上的子查询。你实际上在这里做的是执行一个查询并使用它的结果来查找相关的项目。

你可以连续使用的过滤器,做很多其他的操作对查询集,但它不会被执行,直到你把它切片或致电.values(),但在这里,你实际上是采取了分片

auth_address = b_det[0].#rest of code 

所以你有一个物化查询,你现在试图找到相关作者的地址,这需要另一个查询,但你没有使用,所以django可以自由选择使用哪个数据库。你可以通过使用来克服这个问题select_related

+0

我不认为使用select_related是一个选项,因为我事先并不知道我可能需要执行哪些内部连接。在我的实现中,有6级使用外键引用的表。如果我把所有东西都放在select_related中,那么每次都会成为一个大规模的查询。 – abhayAndPoorvisDad

+0

在您的问题中未提及六种不同的查询。我所回答的是你原来的问题。 – e4c5

+0

好的select_related是解决问题的一种方法。 – abhayAndPoorvisDad

相关问题