【问题标题】:Django model query's database access mechanismdjango模型查询的数据库访问机制
【发布时间】:2017-12-17 17:34:06
【问题描述】:
class parent(models.Model):
    ap=models.CharField(max_length=10)
    user=models.CharField(max_length=10)

    class Meta:
        unique_together=(("ap","user"),)
        db_table='parent'


class child(models.Model):
    userkey=models.ForeignKey(parent,on_delete=models.CASCADE,db_column="ap")
    pn=models.CharField(max_length=10)
    st=models.CharField(max_length=10,default='Y')

    def get_ap(self):
        return self.ap.ap
    def get_pn(self):
        return self.pn
    class Meta:
        db_table="child"
        unique_together=(('userkey','pn'),)

假设我有 ap="apkey" 然后我可以通过以下查询访问“apkey”的所有子模型对象。

child_obj=child.objects.filter(userkey__ap="apkey")

这也可以在不使用外键关系的情况下完成,如下所示。

parent_obj=parent.objects.get(ap="apkey")
child_obj=child.objects.filter(userkey=parent_obj)

我必须知道的是,在这两种方法中执行查询时发生了多少数据库访问。 ?

第二个,我们知道它访问一次父表,然后访问一次子表。因此实际上发生了两个sql查询。

第一个呢?

【问题讨论】:

    标签: mysql django python-2.7 django-models


    【解决方案1】:

    正如@shivam 所说,查询集本质上是惰性的,只有在您请求它们时才会对其进行评估。如果您想查看正在执行的 sql 查询是什么,您可以使用connection。但是您只能看到当前进程的查询。查看正在执行的查询的最佳方法是使用诸如django-debug-tool 之类的工具。

    from django.db import connection
    parent_obj=parent.objects.get(ap="apkey")
    child_obj=child.objects.filter(userkey=parent_obj)
    print(len(connection.queries))
    

    要查看查询,您可以使用查询集的query attribute。它包含要执行的查询。
    例如:

    Mymodels.objects.all().query

    【讨论】:

    • len(connection.queries) 实际上打印了到目前为止使用的查询总数。不是吗?
    • 它们也代表了实际的 mysql 查询,是吗?
    • 是的,它会打印到目前为止使用的查询总数。并且connection.queries 打印出到目前为止进程使用的 sql 查询列表。
    • 这可能会有所帮助。确定后我会回复你的。
    • 我也会尝试调试工具。之后我会回复
    【解决方案2】:

    Django 查询集本质上是惰性的。 see here in documentation。 因此,从技术上讲,当您执行第二段代码时,只会发生一次数据库命中。

    进一步阐述, 从文档中说明。

    q = Entry.objects.filter(headline__startswith="What")
    q = q.filter(pub_date__lte=datetime.date.today())
    q = q.exclude(body_text__icontains="food")
    print(q)
    

    虽然这看起来像是三个数据库命中,但实际上它只命中数据库一次,在最后一行 (print(q))。通常,在您“请求”查询集的结果之前,不会从数据库中获取它们。

    对于后向关系see docs here,在运行 settings.py 时,会创建后向关系,并且从技术上讲,它们也应该只受到一次打击。但我对此并不确定,因为我在我现在记得的文档中没有找到任何关于此的内容。

    希望这会有所帮助。谢谢。

    【讨论】:

    • 感谢您的回复。我正在调查这个
    猜你喜欢
    • 1970-01-01
    • 2012-12-22
    • 2013-04-22
    • 2019-04-14
    • 1970-01-01
    • 2011-04-11
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    相关资源
    最近更新 更多