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

use*_*363 6 postgresql ruby-on-rails

将记录保存到rails 3.2.12&pg 9.3中的postgres数据库时出现错误:

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'
Run Code Online (Sandbox Code Playgroud)

该表工作正常至今(在今天的错误之前保存了大约50条记录).在pgadmin中打开pg表后.我们发现id桌上的是integer.我们Id在其他表上也发现了serial.似乎id应该是serial这样它可以自动增加.如果是的话,如何将一个ID列转换为serialinteger?如果不是,那么如何解决这个问题呢?

poz*_*ozs 8

的数据类型smallserial,serial并且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;


Pro*_*ton 8

我在开发 Rails 6 应用程序时遇到了这样的问题。

我有一个用于创建 a和 an 的User模型:studentadmin

class User < ApplicationRecord
  belongs_to :role
end
Run Code Online (Sandbox Code Playgroud)

以及榜样

class Role < ApplicationRecord
end
Run Code Online (Sandbox Code Playgroud)

但是,我希望在创建它们时分别为每个 和 分配角色,admin而表单中没有角色字段,所以我的模型如下所示:studentadminstudent

管理模型

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
Run Code Online (Sandbox Code Playgroud)

学生模型

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
Run Code Online (Sandbox Code Playgroud)

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

ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR:  null value in column "role_id" violates not-null constraint)
Run Code Online (Sandbox Code Playgroud)

我是这样解决的

问题是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
Run Code Online (Sandbox Code Playgroud)

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

class User < ApplicationRecord
  belongs_to :role, optional: true
end
Run Code Online (Sandbox Code Playgroud)

就这样。

我希望这有帮助

  • 这是完美记录的,正是我正在寻找的!感谢您节省了我的时间! (3认同)