加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – Rails行为错误的Postgres SERIAL NOT NULL列

发布时间:2020-12-17 02:27:28 所属栏目:百科 来源:网络整理
导读:我正在开发一个带有PostgreSQL 8.4数据库后端的(当前)Rails 2.3.x应用程序.在我的Rails应用程序中,我有一个对应于数据库表的模型,该数据库表有两列数据类型SERIAL并设置为NOT NULL.我将这些列中的一个设置为Rails中的主键和PostgreSQL约束. 表定义: CREATE
我正在开发一个带有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值和/或认识到它与’设置为DEFAULT’相同?

我会尝试只是猴子补丁Rails 2.3.x ActiveRecord内部,但我知道如果我这样做,我会被拧到过渡到Rails 3.

我试着用INSFORE INSF中的PL / pgSQL触发器来解决问题,但是我无法弄清楚如何告诉PostgreSQL PL / pgSQL“取消定义”NEW.col2值或者说NEW.col2:= DEFAULT (这不起作用).

答案和/或建议表示赞赏!

解决方法

更简单的方法是定义自己的序列,并在ActiveRecord回调中使用Postgres自己的nextval(). nextval()处理在一个原子操作中向前推进序列一步,并返回下一个值.

在迁移中:

def self.up
    execute "CREATE SEQUENCE myseq"
end

def self.down
    execute "DROP SEQUENCE myseq"
end

在模型中:

before_save :set_column_from_sequence,:on => :create

def set_column_from_sequence
    self.mycolumn = self.class.connection.select_value("SELECT nextval('myseq')")
end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读