Django尝试写入生成的列

8

我已经为我的数据库添加了GIN索引。

ALTER TABLE mtn_order
ADD COLUMN textsearchable_index_col tsvector
GENERATED ALWAYS AS (to_tsvector('english', coalesce(descr, '') || ' ' || coalesce(descrrep, ''))) STORED;
CREATE INDEX textsearch_idx ON mtn_order USING GIN (textsearchable_index_col);

我将 textsearchable_index_col = SearchVectorField(null=True) 添加到我的模型中,现在当我尝试保存新实例时,会出现以下错误:
ProgrammingError at /order/create/
cannot insert into column "textsearchable_index_col"
DETAIL:  Column "textsearchable_index_col" is a generated column.

如何阻止Django尝试将None写入该字段
2个回答

5
你无法将它作为模型的字段添加,因为Django会尝试将值写回它。 当需要时,你可以在其上进行注释。
MyModel.objects.annotate(
    index_col=RawSQL('textsearchable_index_col', 
                     [], 
                     output_field=SearchVectorField()
)

1
对于那些希望跟踪生成列而不必求助于原始SQL调用的人,请关注这个Django项目票证:https://code.djangoproject.com/ticket/30511 - jorf.brunning
那个票据看起来好像只限于生成身份列? - Matthew Schinckel
我也曾经这样想过,但是 Django 社区会关闭任何 GENERATED AS 功能的票并将其标记为重复,并指向我之前链接的票。例如:https://code.djangoproject.com/ticket/31565 和 https://code.djangoproject.com/ticket/31300。 - jorf.brunning
我认为建议是通过#30511解决任何生成的AS列的基础设施和功能。 - Matthew Schinckel

0
在模型上重写_do_insert和_do_update方法:
class MTNOrder:

    def _do_insert(self, manager, using, fields, update_pk, raw):
        fields = [
            f for f in fields if f.attname not in ['textsearchable_index_col']
        ]
        return super()._do_insert(manager, using, fields, update_pk, raw)

    def _do_update(self, base_qs, using, pk_val, values, update_fields, forced_update):
        values = [
            value for value in values if value[0].attname not in ['textsearchable_index_col']
        ]
        return super()._do_update(base_qs, using, pk_val, values, update_fields, forced_update)

参考:如何让Django不插入某些字段


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接