Транзакция / RawSequel - и радости тестирования - PullRequest
0 голосов
/ 12 августа 2011

Оба они работают в «производстве», позже работает только в тестировании. Теперь, когда у меня есть кое-что для работы и в производстве, и в тестировании, я хотел бы понять, почему мне пришлось идти по всему маршруту, а не по маршруту Джанго. Я считаю, что проблема связана с транзакциями, но я не уверен, и когда я сижу здесь в 8:30 вечера, меня это беспокоит.

Это относится к этому вопросу , где я думал, что у меня есть свой ответ (и понимание), но, увы, я этого не сделал. Мое тестирование - это A / B, где A вводится за пределами Django, а B сравнивается с известным A. Ответ, который был предоставлен, решил часть моей проблемы, но когда я добавил дополнительные тесты, проблема продолжала всплывать.

Я зарылся и предположил, что RawQuery не совершал транзакцию, но никакая сумма Transactions.commit , похоже, не могла это исправить. Я также удалил django.testing.TestCase из него и пошел прямо. Я думаю, что перепробовал каждую комбинацию, но я не очень хорошо разбираюсь в поддержке SQL или Transactional, и теперь мне интересно, почему один работает, а другой нет ...

Если у кого-то есть понимание, я был бы очень признателен!

Обновление 2 Пересмотрен и очищен, но все еще не работает ..

    # BUG: https://code.djangoproject.com/ticket/12768
    # - Requirement for pmProp.* - This (in-part) forced me to shift to raw.
    sqlraw = """ SELECT
                    pmProp.propid as propid_id,
                    pmProp.owner as owner,
                    pmProp.ownertype as ownertype,
                    pmProp.behavior as behavior,
                    pmProp.value as value_id,
                    pmPropDef.id as propdef_id,
                    pmPropDef.name as name,
                    pmPropDef.datatype as datatype,
                    pmPropDef.choicetype as choicetype,
                    pmPropDef.definition as definition_id,
                    pmPropDef.ptrig as prop_trigger,
                    pmPropDef.units as units,
                    IFNULL(pmPropShort.str, pmPropLong.str) as str_value FROM pmProp
                INNER JOIN pmPropDef ON pmProp.propid=pmPropDef.id AND pmPropDef.name=%s
                LEFT JOIN pmPropShort ON sid=pmProp.value
                LEFT JOIN pmPropLong ON lid=-pmProp.value
                WHERE pmProp.ownertype=%s AND pmProp.owner=%s AND pmPropDef.id=pmProp.propid
                """
    if explicit:
            sqlraw += " AND pmProp.behavior='explicit'"

    # TRY ONE - DOES NOT WORK FOR TESTING..
    # This will NOT work for testing - It simply doesn't get the value
    # when repeatedly inserting from pm and checking the value.
    #
    # Note if you use this you must update the sqlraw to include pmProp.* bug..
    #
    #try:
    #    result = list(Property.objects.raw(sqlraw, [property, owner, self.id]))[0]
    #    result.value = self.coerce_datatype(result.str_val, result.datatype)
    #except IndexError:
    #    result = None
    # END TRY ONE

    # Try TWO:  THIS WORKS for both
    cursor = connections['catalog'].cursor()
    cursor.execute(sqlraw, [property, owner, self.id])
    row = cursor.fetchone()
    transaction.commit_unless_managed(using='catalog')

    if row:
        field_map =  "propid_id owner ownertype behavior value_id propdef_id "
        field_map += "name datatype choicetype definition_id prop_trigger "
        field_map +=  "units str_value"
        field_map = field_map.split()
        class PropVal(object): pass
        result = PropVal()
        result.__dict__=dict(zip(field_map, row))
        result.value = self.coerce_datatype(result.str_value, result.datatype)
        try:
            log.info("%s %s=%s %s" % (property.capitalize(), result.name,
                                               result.value, result.units))
        except UnicodeDecodeError: pass
    else:
        result = None
    # END TRY Two

Обновление

Вот пример теста А / Б.

from django.db import connection, transaction
from unittest import TestCase
#from django.test import TestCase, TransactionTestCase
from apps.pmCatalog.utility.ICMPM.pm import Pm
from apps.pmCatalog.models import Property, Site, Project, Variant, Library, LibraryType, Release
import settings
import datetime

import logging
log = logging.getLogger(__name__)

class PropertyTests(TestCase):

    def test_add_property_value(self):
        """Test the ability to add a property and retrieve a property"""

        prop_types = [("string", "Funny Business"), ("integer", 1234), ("real", 12.34) ]
        pm = Pm(mysql_db='test_bugs')
        tree = pm.add_release_tree()

        for prop_type, pmvalue in prop_types:
            # Add a property definition for a branch (like a project)
            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)
            #Project.objects.update()
            project = Project.objects.get(name=pmproject.name)
            property = project.get_property(pmproperty)
            #When using the first one this ALWAYS returned None!
            self.assertEqual(str(pmvalue), property.str_value)
            self.assertEqual(pmvalue, property.value)

Спасибо!

1 Ответ

1 голос
/ 12 августа 2011

Я вижу две проблемы в

sqlraw = """SELECT pmProp.*, pmPropDef.id, pmPropDef.name, pmPropDef.units,
            IFNULL(pmPropShort.str, pmPropLong.str) as value FROM pmProp
            INNER JOIN pmPropDef ON pmProp.propid=pmPropDef.id AND pmPropDef.name=%s
            LEFT JOIN pmPropShort ON sid=pmProp.value
            LEFT JOIN pmPropLong ON lid=-pmProp.value
            WHERE pmProp.ownertype=%s AND pmProp.owner=%s AND pmPropDef.id = pmProp.propid
            """
  1. , которые вы получаете pmPropDef.id и pmProp.propid, даже если они равны и первая не будет отображаться в Property field.

  2. в целом, используя запрос .raw(), вы должны вернуть правильные имена (либо используя SELECT pmPropDef.name AS name и т. Д. Для каждого поля, либо используя необязательныйпреобразовать карту в метод raw (), который сопоставит столбцы со свойствами. Легко вернуть непосредственно фактические имена

Попробуйте выполнить следующее (отрегулируйте в соответствии с фактическими именами столбцов в таблицеи имена полей в модели):

sqlraw = """SELECT 
                pmProp.id as id,
                pmProp.owner as owner,
                pmProp.ownertype as ownertype,
                pmProp.behavior as behavior,
                pmProp.propdef_id as propdef_id,
                pmPropDef.name as name, 
                pmPropDef.units as units,
                IFNULL(pmPropShort.str, pmPropLong.str) as str_value
            FROM pmProp
            INNER JOIN pmPropDef ON pmProp.propid=pmPropDef.id AND pmPropDef.name=%s
            LEFT JOIN pmPropShort ON sid=pmProp.value
            LEFT JOIN pmPropLong ON lid=-pmProp.value
            WHERE pmProp.ownertype=%s AND pmProp.owner=%s AND pmPropDef.id = pmProp.propid
            """

Если вы действительно уже нуждаетесь в приведенном значении, попробуйте привести его в тот же запрос.

...