【问题标题】:Testing triggers for fulltext search in Django在 Django 中测试全文搜索的触发器
【发布时间】:2019-07-24 19:29:32
【问题描述】:

我正在向 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 实例的问题相同,但答案应该非常相似。

感谢任何提示;)

【问题讨论】:

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


    【解决方案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)
    

    【讨论】:

    • 但是你必须手动构建你的 search_list... 我想避免这种情况,因为 1) 我在模拟一切 -> 我需要停止模拟这些测试的对象或实现一个函数,在给定输入的情况下构建search_list 2) 我需要知道我期望的确切结果更准确地说,我知道search 反映了content 的内容,但是使用上述方法,我需要使用 PostgreSQL 来知道 search 的期望值,因为在 Python 中实现搜索向量的创建将是低效且冗余的。
    • 通常我只处理了测试中的值来与我期望的比较值进行比较,它只是工作,尝试它并报告它是否也适合你。您最后指定的需求不在您的问题中,如果您想要一个具体的答案,我建议您在主要问题中添加您最后评论的内容。
    • 如果你像我一样在你的测试中模拟一切,比较Document.objects.values_list('search', flat=True)[item.search_vector for item in Document.objects.annotate(search_vector=SearchVector('content', config='yourconfig'))]
    猜你喜欢
    • 2013-05-23
    • 1970-01-01
    • 2020-08-12
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多