PG :: NotNullViolation:ERROR:列中的空值" id"违反非空约束

时间:2014-06-19 03:11:48

标签: ruby-on-rails postgresql

将记录保存到rails 3.2.12&上的postgres数据库时出现错误。第9.3页:

ActiveRecord::StatementInvalid (PG::NotNullViolation: ERROR:  null value in column "id" violates not-null constraint
: INSERT INTO "sw_module_infox_module_infos" ("about_controller", "about_init", "about_log", "about_misc_def", "about_model", "about_onboard_data", "about_subaction", "about_view", "about_workflow", "active", "api_spec", "category_id", "created_at", "last_updated_by_id", "module_desp", "name", "submit_date", "submitted_by_id", "updated_at", "version", "wf_state") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21) RETURNING "id"):
  activerecord (3.2.12) lib/active_record/connection_adapters/postgresql_adapter.rb:1166:in `get_last_result'
  activerecord (3.2.12) lib/active_record/connection_adapters/postgresql_adapter.rb:1166:in `exec_cache'

该表工作正常至今(在今天的错误之前保存了大约50条记录)。在pgadmin中打开pg表后。我们发现表格中的idinteger。我们还发现其他表上的Idserial。似乎id应为serial,因此它可以自动递增。如果是,那么如何将{id}列从serial转换为integer?如果不是,那么如何解决这个问题呢?

3 个答案:

答案 0 :(得分:8)

  

数据类型smallserial, serial and bigserial不是真正的类型,而只是用于创建唯一标识符列的符号方便(类似于某些其他数据库支持的AUTO_INCREMENT属性)。

如果你的专栏是integer,你就不能转换为serial,但你可以模仿PostgreSQL会做什么,就像你创建你的表一样一个连续剧:

CREATE SEQUENCE tablename_colname_seq;
ALTER TABLE tablename ALTER COLUMN colname SET DEFAULT nextval('tablename_colname_seq'::regclass);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

答案 1 :(得分:2)

在Rails 6应用程序上工作时遇到这样的问题。

我有一个 User 模型,该模型用于创建studentadmin

class User < ApplicationRecord
  belongs_to :role
end

角色模型:

class Role < ApplicationRecord
end

但是,我希望在创建它们时分别为每个adminstudent分别分配adminstudent角色,而在中不包含角色字段表单,所以我的模型是这样的:

管理员模型:

class Admin < ApplicationRecord
  before_save :set_admin_role

  belongs_to :user

  private

  def set_admin_role
    # set role_id to '1' except if role_id is not empty
    user.role_id = '1' if user.role_id.nil?
  end
end

学生模型:

class Student < ApplicationRecord
  before_save :set_student_role

  belongs_to :user

  private

  def set_student_role
    # set role_id to '2' except if role_id is not empty
    user.role_id = '2' if user.role_id.nil?
  end
end

因此,每当我尝试创建管理员和学生时,这都会引发错误:

ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR:  null value in column "role_id" violates not-null constraint)

这是我的解决方法

问题是role_id表中的users在我的迁移文件中设置为null: false。我不得不将其更改为null: true

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :email
      t.string :password_digest
      t.references :role, null: true, foreign_key: true

      t.timestamps
    end
  end
end

然后还更改了用户模型,以将role_id设为可选:

class User < ApplicationRecord
  belongs_to :role, optional: true
end

仅此而已。

我希望这会有所帮助

答案 2 :(得分:0)

我有一个非常相似的问题。

我会告诉你出了什么问题,也许有人会觉得我的经验有用

我有ERROR: null value in column "created_at" violates not-null constraint

问题是我有一个在before_createbefore_save中运行的方法,并且此方法试图通过较小的更新进行保存。因此它试图节省几次。

我的建议是检查您的代码在before_save中的作用 和before_create

相关问题