我正在开发一个(当前)带有 PostgreSQL 8.4 数据库后端的 Rails 2.3.x 应用程序。在我的 Rails 应用程序中,我有一个与数据库表相对应的模型,该表具有两列数据类型为 SERIAL 并设置为 NOT NULL。我将这些列之一设置为 Rails 中的主键和 PostgreSQL 约束。
表定义:
CREATE TABLE problem_table
(
col1 serial NOT NULL,
col2 serial NOT NULL,
other_col1 character varying,
other_col2 character varying,
...,
CONSTRAINT problem_table_pkey PRIMARY KEY (col1)
);
模型类定义:
class ModelClass1 < ActiveRecord::Base
self.table_name = 'problem_table'
self.primary_key = 'col1'
end
我的问题是关于非主键 SERIAL NOT NULL 列。当我尝试执行 Rails ActiveRecord::Base#create 时,Rails 正确地没有为主键 SERIAL NOT NULL 列设置值,而是为另一个列设置了 NULL 值,这导致 PostgreSQL 抱怨NOT NULL 列被设置为 NULL。
我告诉 Rails 做什么:
ModelClass1.create(
other_col1: 'normal'
other_col2: 'data',
...
);
Rails 告诉 PostgreSQL:
INSERT INTO problem_table (
col2,
other_col1,
other_col2,
...
) VALUES (
NULL,
'normal',
'data',
...
);
我的问题是,如何让 Rails 停止为该列传递 NULL 并且不传递任何内容,让 DEFAULT nextval(my_seq) 接管?或者,如果这是不可能的,我怎么能告诉 PostgreSQL 在传递时忽略这个 NULL 值和/或识别它与“设置为默认值”相同?
我会尝试只修补 Rails 2.3.x ActiveRecord 内部,但我知道如果我这样做了,在过渡到 Rails 3 时我会搞砸的。
我已经研究过在插入之前尝试使用 PL/pgSQL 触发器来修复问题,但我不知道如何使用 PL/pgSQL 告诉 PostgreSQL 来“取消定义”NEW.col2 值或说 NEW.col2 := DEFAULT (这不起作用)。
答案和/或建议表示赞赏!