Django测试 - 外部修改数据时的多个查询。缓存问题? [英] Django testing - Multiple queries when externally modifying the data. Cache Issue?

查看:145
本文介绍了Django测试 - 外部修改数据时的多个查询。缓存问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个旧版应用程序(目前)使用Django来有效显示数据。我的一个工作测试的样本看起来像这样。

  def test_add_property_value(self):
Test设置/获取一个值
#这将做一些外部进程发生在db上。
pm = Pm(mysql_db ='test_bugs')
tree = pm.add_release_tree()
prop_type,pmvalue =(string,Funny Business)
pmproperty = %s_%s_basic%(tree [0] .name,prop_type)
pm.add_property_definition(pmproperty,prop_type = prop_type)
pm.add_propval(pmproperty,value = pmvalue,project = tree [ 。$)

#现在使用Django将值退出..
project = Project.objects.get(name = tree [0] .name)
property = project.get_property(pmproperty)#自定义查询使用sql.raw
self.assertEqual(pmvalue,property.value)

您可以看到它是基本的A / B测试。现在我发现了一个局限性,我似乎无法解决这个多个外部添加检查循环查询失败。修改上述代码失败,因为它出现查询无法甚至运行

  def test_add_property_value(self):
测试设置/获取值

#这将做一些外部进程,发生在db上。
pm = Pm(mysql_db ='test_bugs',p4_port = settings.ICMSERVER_TEST_PORT)
tree = pm.add_release_tree()
prop_type,pmvalue =(string,Funny Business)
pmproperty =%s_%s_basic%(tree [1] .name,prop_type)
pm.add_property_definition(pmproperty,prop_type = prop_type)
pm.add_propval(pmproperty,value = pmvalue, project = tree [1] .name)

#现在使用Django将值退出..
project = Project.objects.get(name = tree [1] .name)
property = project.get_property(pmproperty)
self.assertEqual(pmvalue,property.value)

#只有更改才能添加这个

#这将做一些发生在db上的外部进程。
pmproperty =%s_%s_basic_two%(tree [1] .name,prop_type)
pm.add_property_definition(pmproperty,prop_type = prop_type)
pm.add_propval(pmproperty,value = pmvalue ,project = tree [1] .name)

#现在使用Django将值退出..
project = Project.objects.get(name = tree [1] .name )
property = project.get_property(pmproperty)
self.assertEqual(pmvalue,property.value)

我已经阅读过 CACHE_BACKEND 但似乎没有帮助。任何其他的想法?经过进一步调查,这似乎与我的外部db完全不相关。 Arghh ..感觉像星期一!


  1. 这是一个缓存问题BTW - 设置CACHE_BACKEND ='dummy:///'或'locmem :///'did nothing。

  2. 如何更好地诊断这个问题?

感谢



更新



这是最后的答案 - 2小调整。根据 Daniel Severio 的。非常感谢指针!

 类PropertyTests(TransactionTestCase):#CHANGE1 
def test_add_property_value(self):
设置/获取一个值

import logging
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())

#这将做一些外部进程,发生在db上。
pm = Pm(mysql_db ='test_bugs',p4_port = settings.ICMSERVER_TEST_PORT)
tree = pm.add_release_tree()
prop_type,pmvalue =(string,Funny Business)
pmproperty =%s_%s_basic%(tree [1] .name,prop_type)
pm.add_property_definition(pmproperty,prop_type = prop_type)
pm.add_propval(pmproperty,value = pmvalue, project = tree [1] .name)

#现在使用Django将值退出..
project = Project.objects.get(name = tree [1] .name)
property = project.get_property(pmproperty)
self.assertEqual(pmvalue,property.value)

#这将执行一些与db相关的外部进程。
pmproperty =%s_%s_basic_two%(tree [1] .name,prop_type)
pm.add_property_definition(pmproperty,prop_type = prop_type)
pm.add_propval(pmproperty,value = pmvalue ,project = tree [1] .name)

#现在使用Django将值退出..
Project.objects.update()#CHANGE2
project = Project .objects.get(name = tree [1] .name)
property = project.get_property(pmproperty)
self.assertEqual(pmvalue,property.value)


解决方案

这可能不是交易问题。需要向Manager( Project.objects )通知数据更改,因为它的设计是在短时间内生活。



您正在查询两次相同的查询 Project.objects.get(name = tree [1] .name),并且管理器将不会再执行,因为它认为它已经有正确的数据。



在第二个查询之前,执行

  Project.objects.update()

使管理器缓存无效。无效之后的结果应该是最新的。


I have a legacy application which is (currently) using Django to effectively display data. A sample of one of my working tests looks like this.

def test_add_property_value(self):
    """Test set / get a value"""
    # This will do some external process which occcurs to the db.
    pm = Pm(mysql_db='test_bugs')
    tree =  pm.add_release_tree()
    prop_type, pmvalue = ("string", "Funny Business")
    pmproperty = "%s_%s_basic" % (tree[0].name, prop_type)
    pm.add_property_definition(pmproperty, prop_type=prop_type)
    pm.add_propval(pmproperty, value=pmvalue, project=tree[0].name)

    # Now use Django to pull the value back out..
    project = Project.objects.get(name=tree[0].name)
    property = project.get_property(pmproperty) # Custom query using sql.raw
    self.assertEqual(pmvalue, property.value)

As you can see it's basic A/B Testing. Now I've found a limitations and I can't seem to get around in that multiple external add - check - loop queries are failing. Modifying the above code fails because it appears query is failing to even run.

def test_add_property_value(self):
    """Test set / get a value"""

    # This will do some external process which occcurs to the db.
    pm = Pm(mysql_db='test_bugs', p4_port = settings.ICMSERVER_TEST_PORT)
    tree = pm.add_release_tree()
    prop_type, pmvalue = ("string", "Funny Business")
    pmproperty = "%s_%s_basic" % (tree[1].name, prop_type)
    pm.add_property_definition(pmproperty, prop_type=prop_type)
    pm.add_propval(pmproperty, value=pmvalue, project=tree[1].name)

    # Now use Django to pull the value back out..
    project = Project.objects.get(name=tree[1].name)
    property = project.get_property(pmproperty)
    self.assertEqual(pmvalue, property.value)

    # ONLY CHANGE WAS TO ADD THIS..

    # This will do some external process which occcurs to the db.
    pmproperty = "%s_%s_basic_two" % (tree[1].name, prop_type)
    pm.add_property_definition(pmproperty, prop_type=prop_type)
    pm.add_propval(pmproperty, value=pmvalue, project=tree[1].name)

    # Now use Django to pull the value back out..
    project = Project.objects.get(name=tree[1].name)
    property = project.get_property(pmproperty)
    self.assertEqual(pmvalue, property.value)

I've read about the CACHE_BACKEND but that didn't seem to help. Any other ideas?? After further investigation this appears to not be related to my external db at all. Arghh.. It feels like monday!

  1. Is this a cache problem BTW - Setting CACHE_BACKEND = 'dummy:///' or 'locmem:///' did nothing.
  2. How do I better diagnosis this problem??

Thanks

Update

Here was the final answer - 2 small tweaks.. Based on Daniel and Severio. Much appreciated the pointers!!

class PropertyTests(TransactionTestCase):  #CHANGE1
    def test_add_property_value(self):
        """Test set / get a value"""

        import logging
        l = logging.getLogger('django.db.backends')
        l.setLevel(logging.DEBUG)
        l.addHandler(logging.StreamHandler())

        # This will do some external process which occcurs to the db.
        pm = Pm(mysql_db='test_bugs', p4_port = settings.ICMSERVER_TEST_PORT)
        tree = pm.add_release_tree()
        prop_type, pmvalue = ("string", "Funny Business")
        pmproperty = "%s_%s_basic" % (tree[1].name, prop_type)
        pm.add_property_definition(pmproperty, prop_type=prop_type)
        pm.add_propval(pmproperty, value=pmvalue, project=tree[1].name)

        # Now use Django to pull the value back out..
        project = Project.objects.get(name=tree[1].name)
        property = project.get_property(pmproperty)
        self.assertEqual(pmvalue, property.value)

        # This will do some external process which occcurs to the db.
        pmproperty = "%s_%s_basic_two" % (tree[1].name, prop_type)
        pm.add_property_definition(pmproperty, prop_type=prop_type)
        pm.add_propval(pmproperty, value=pmvalue, project=tree[1].name)

        # Now use Django to pull the value back out..
        Project.objects.update() #CHANGE2
        project = Project.objects.get(name=tree[1].name)
        property = project.get_property(pmproperty)
        self.assertEqual(pmvalue, property.value)

解决方案

That's probably not a transaction issue. The Manager (Project.objects) needs to be informed of a data change, because it's designed to live for a short period of time.

You are querying twice the same query Project.objects.get(name=tree[1].name) and the manager won't execute it again, because it thinks it has already the correct data.

Just before the second query, do

Project.objects.update()

to invalidate the manager cache. The results after the invalidation should be up to date.

这篇关于Django测试 - 外部修改数据时的多个查询。缓存问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆