在Django中测试全文搜索的触发器

时间:2019-03-03 08:48:16

标签: django postgresql unit-testing full-text-search django-queryset

我将搜索引擎添加到Django项目中,从而使用自定义触发器在多个模型上设置SearchVectorFields。

我想对模型实例更改时对TSVECTOR类型的列进行单元测试。

但是,我一直找不到有关如何测试SearchVectorField内容的任何信息...我无法将my_document.searchSearchVector(Value("document content"))或类似的东西进行比较,因为第一个似乎是像字符串一样,而后者是一个对象。

TL; DR

更准确地说,使用模型:

from django.db import models

class Document(models.Model):
    ...
    content = TextField()
    search = SearchVectorField()

并触发:

-- create trigger function
CREATE OR REPLACE FUNCTION search_trigger() RETURNS trigger AS $$
begin
    NEW.search := to_tsvector(COALESCE(NEW.content, ''))
    return NEW;
end
$$ LANGUAGE plpgsql;
-- add trigger on insert
DROP TRIGGER IF EXISTS search_trigger ON myapp_document;
CREATE TRIGGER search_trigger
BEFORE INSERT
ON myapp_document
FOR EACH ROW
EXECUTE PROCEDURE search_trigger();
-- add trigger on update
DROP TRIGGER IF EXISTS search_trigger_update ON myapp_document;
CREATE TRIGGER search_trigger_update
BEFORE UPDATE OF content
ON myapp_document
FOR EACH ROW
WHEN (OLD.content IS DISTINCT FROM NEW.content)
EXECUTE PROCEDURE search_trigger();

如何测试创建新的Document实例时,在其search字段中用正确的值填充 ?更新现有Document实例的问题相同,但答案应该非常相似。

感谢任何提示;)

1 个答案:

答案 0 :(得分:1)

我认为您可以比较SearchVectorField值的字符串表示形式:

from django.test import TestCase

from .models import Document


class DocumentTest(TestCase):

    def setUp(self):
        Document.objects.create(content='Pizza Recipes')

    def test_document_search(self):
        document_list = list(Document.objects.values_list('search', flat=True))
        search_list = ["'pizza':1 'recip':2"]
        self.assertSequenceEqual(document_list, search_list)