django子查询使用的数据库是粘的吗?

时间:2016-11-04 06:25:01

标签: django-models celery

我遇到了django子查询的问题。当我获取原始QuerySet时,我指定了我需要使用的数据库。我的预感是,后面的子查询最终使用'default'数据库而不是父查询使用的数据库。

我的模型大致如此(我有几个): -

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)

现在我获取一个QuerySet来表示所有被称为Mark的书籍: -

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

然后在代码中的某处,我通过执行以下操作来触发子查询: -

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

我的问题是在某些情况下,在我的实时服务器上任意,即使有该作者id的有效数据,子查询也会失败。我怀疑子查询没有使用相同的数据库'some_db'。这可能吗?是否需要使用的数据库在子查询中不粘?这只是一个预感,这可能是一个问题,它发生在一个芹菜工人的背景下,芹菜与django ORM的组合有可能有一些错误吗?

我每次通过调用 select_related 进行完全提取就解决了这个问题。

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

所以现在,我解决问题的唯一方法是事先确定我需要的所有数据,并确保顶级fetch使用 select_related 进行所有内部模型引用。任何想法为何会失败的想法?

我无法在本地重新创建,否则我会调试它。就像我说的那样,它很随意。

1 个答案:

答案 0 :(得分:0)

好的,我现在处理这个问题。我认为子查询对原始数据库保持粘性的假设是错误的。 django所做的是首先它击中配置的数据库路由器。如果仅在这种情况下不返回任何内容,则它会使用原始数据库。

因此,如果配置的数据库路由器返回一些要使用的数据库,那么就会使用它。在我看来这是错误的,我们需要先使用原始数据库,然后检查数据库路由器。