带生成索引字段时,如何用Django ORM向PostgreSQL插入数据
Django ORM插入含生成列模型报错解决
问题背景
我有一个带文本字段的模型,为实现搜索功能在该字段上创建了索引,模型定义如下:
class my_model(models.Model): text = models.TextField(null=True) vector = SearchVectorField(null=True, default='') # 多对多字段 ents = models.ManyToManyField(ent) class ent(models.Model): ph = models.TextField(unique=True) ty = models.TextField()
之前用INSERT语句插入数据时,不提供vector字段的值一切正常。但现在给模型加了多对多字段,因为没创建显式中间表,想改用Django ORM插入数据,执行以下代码时报错:
a1 = my_model(text='test') a1.save()
错误信息:
ProgrammingError: column "vector" can only be updated to DEFAULT DETAIL: Column "vector" is a generated column.
尝试手动指定vector=''插入,仍报同样错误:
a1 = my_model(text='test', vector = '') a1.save()
问题原因
SearchVectorField对应的是数据库中的生成列,这类字段的值由数据库自动计算生成,不允许手动赋值或通过ORM设置默认值覆盖其生成逻辑。
解决方法
方法1:修正模型字段配置
- 移除
vector字段的default=''参数,生成列无需手动指定默认值:
class my_model(models.Model): text = models.TextField(null=True) vector = SearchVectorField(null=True) ents = models.ManyToManyField(ent)
- 执行迁移命令更新数据库表结构:
python manage.py makemigrations python manage.py migrate
- 重新用ORM插入数据,只需指定
text字段:
a1 = my_model(text='test') a1.save()
方法2:指定更新字段(适合已存在的生成列)
如果数据库中已经是生成列,不想修改模型迁移,可以在save时指定update_fields参数,只更新需要的字段,跳过vector:
a1 = my_model(text='test') a1.save(update_fields=['text'])
内容的提问来源于stack exchange,提问作者keramat
相关产品推荐
相关产品推荐

