4

这是这些健全性检查问题之一。这应该非常明显。要么是司机出了问题,要么我忽略了一些明显的事情。

我有一个 Django 模型字段。它是一个整数字段,非空,有选择。

PROVENANCE_X = 0
PROVENANCE_Y = 1

PROVENANCE_CHOICES = [
    (PROVENANCE_X, "Provenance X"),
    (PROVENANCE_Y, "Provenance Y")
]

在模型中:

provenance = models.IntegerField(choices=PROVENANCE_CHOICES, default=PROVENANCE_X)

只是为了检查一下,这是 Postgres 所说的:

provenance     | integer                 | not null

当我在管理员中保存模型时出现错误。

DatabaseError
column "provenance" is not of a character type

没有自定义的管理内容。错误完全出在 Django 代码中,但我不知道在哪里。save在调用 super 之前,我在方法中设置了一个断点来检查:

(Pdb) print self.provenance
0

那么某些代码是否在某处试图插入一个字符而不是一个整数?

错误来自django/db/backends/postgresql_psycopg2/base.py.

该堆栈帧的本地查询变量:

'INSERT INTO "MODEL" ("A", "provenance", "B", "C") VALUES (%s, %s, %s, %s) RETURNING "MODEL"."id"'
args
(False,
 0,
 u'test',
 '098f6bcd4621d373cade4e832627b4f6',
 )

这表明查询构建接收正确的参数 (0)。注意 '%s' 不是标准格式的占位符,因为 Django 查询构建%s是唯一的类型。

所以这一切看起来都是正确的。

这是怎么回事?

4

1 回答 1

5

我追踪了它。就像最好的追踪一样,有点故事。

backends/postgresql_psycopg2/base.py首先,我在in 中设置了一个断点,CursorWrapper.execute并确定无法单步执行 with pdb,因此它必须是 C 模块。

因此,我搜索了确切的错误“不是字符类型”,这使我找到了tsvector用于全文搜索的 PostgreSQL 源代码。该行:

01419         if (!is_text_type(SPI_gettypeid(rel->rd_att, numattr)))
01420             ereport(ERROR,
01421                     (errcode(ERRCODE_DATATYPE_MISMATCH),
01422                      errmsg("column \"%s\" is not of a character type",
01423               trigger->tgargs[i])));

http://doxygen.postgresql.org/tsvector__op_8c_source.html中找到

因此,它试图在相关领域之外创建一个 tsvector。

所以我查看了模式,你瞧,我有一个触发器。

Triggers:
MY_TRIGGER BEFORE INSERT OR UPDATE ON MY_TABLE FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger('text_index', 'pg_catalog.english', 'X', 'Y', 'Z', 'provenance')

我忘记了这件事。我不知道为什么它以前工作,然后停止工作,但这就是问题所在。

tl;dr 更新触发器正在构建tsvector字段外,并且正在抱怨该类型。数据或驱动程序没有任何问题,只是触发器执行了错误的数据类型。

于 2012-12-24T16:48:50.207 回答