如何阻止 Go gorm 对我在 Postgres 中的自引用外键强制非空约束
How to stop Go gorm from forcing a not null constraint on my self referencing foreign key in Postgres
我需要创建一个在 gorm 中引用自身的 table,但无法弄清楚为什么它会对我施加 not null
约束。我完全被难住了。我该如何解决这个问题?我正在使用 gorm 提供的 AutoMigrate 功能来创建 table。在我删除外键约束的那一刻,not null
约束就消失了,但这不是我想要的。
已编辑: 我正在使用包“gorm.io/gorm”,而不是 Github 上的包。这也是唯一给我问题的 table,任何其他具有引用其他 table 的外键的 table 都按预期工作。
使用外键
type User struct {
ID *int `gorm:"primaryKey; type:serial"`
Username string `gorm:"type: varchar(32) not null unique"`
Password string `gorm:"type: varchar(128) not null"`
ReferredBy *int
Referrer *User `gorm:"foreignKey:ReferredBy;constraint:OnUpdate:CASCADE,ONDELETE:SET NULL"`
}
根据 pgAdmin
使用外键生成 SQL
-- Table: public.users
-- DROP TABLE public.users;
CREATE TABLE public.users
(
id integer NOT NULL DEFAULT nextval('users_id_seq'::regclass),
username character varying(32) COLLATE pg_catalog."default" NOT NULL,
password character varying(128) COLLATE pg_catalog."default" NOT NULL,
referred_by integer NOT NULL DEFAULT nextval('users_referred_by_seq'::regclass),
CONSTRAINT users_pkey PRIMARY KEY (id),
CONSTRAINT users_username_key UNIQUE (username),
CONSTRAINT fk_users_referrer FOREIGN KEY (referred_by)
REFERENCES public.users (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE SET NULL
)
TABLESPACE pg_default;
ALTER TABLE public.users
OWNER to msmf;
没有外键
// User Model. ReferredBy is self referencing Foreign Key
type User struct {
ID *int `gorm:"primaryKey; type:serial"`
Username string `gorm:"type: varchar(32) not null unique"`
Password string `gorm:"type: varchar(128) not null"`
ReferredBy *int
}
结果SQL 没有告诉 gorm 有一个外键
-- Table: public.users
-- DROP TABLE public.users;
CREATE TABLE public.users
(
id integer NOT NULL DEFAULT nextval('users_id_seq'::regclass),
username character varying(32) COLLATE pg_catalog."default" NOT NULL,
password character varying(128) COLLATE pg_catalog."default" NOT NULL,
referred_by bigint,
CONSTRAINT users_pkey PRIMARY KEY (id),
CONSTRAINT users_username_key UNIQUE (username)
)
TABLESPACE pg_default;
ALTER TABLE public.users
OWNER to msmf;
显然 type:serial
标签可以做到这一点。如果你放弃它,那么 not null 约束也不会存在:
type User struct {
ID uint `gorm:"primarykey"`
Username string `gorm:"type: varchar(32) not null unique"`
Password string `gorm:"type: varchar(128) not null"`
ReferredBy *int
Referrer *User `gorm:"foreignKey:ReferredBy;constraint:OnUpdate:CASCADE,ONDELETE:SET NULL;"`
}
我需要创建一个在 gorm 中引用自身的 table,但无法弄清楚为什么它会对我施加 not null
约束。我完全被难住了。我该如何解决这个问题?我正在使用 gorm 提供的 AutoMigrate 功能来创建 table。在我删除外键约束的那一刻,not null
约束就消失了,但这不是我想要的。
已编辑: 我正在使用包“gorm.io/gorm”,而不是 Github 上的包。这也是唯一给我问题的 table,任何其他具有引用其他 table 的外键的 table 都按预期工作。
使用外键
type User struct {
ID *int `gorm:"primaryKey; type:serial"`
Username string `gorm:"type: varchar(32) not null unique"`
Password string `gorm:"type: varchar(128) not null"`
ReferredBy *int
Referrer *User `gorm:"foreignKey:ReferredBy;constraint:OnUpdate:CASCADE,ONDELETE:SET NULL"`
}
根据 pgAdmin
使用外键生成 SQL-- Table: public.users
-- DROP TABLE public.users;
CREATE TABLE public.users
(
id integer NOT NULL DEFAULT nextval('users_id_seq'::regclass),
username character varying(32) COLLATE pg_catalog."default" NOT NULL,
password character varying(128) COLLATE pg_catalog."default" NOT NULL,
referred_by integer NOT NULL DEFAULT nextval('users_referred_by_seq'::regclass),
CONSTRAINT users_pkey PRIMARY KEY (id),
CONSTRAINT users_username_key UNIQUE (username),
CONSTRAINT fk_users_referrer FOREIGN KEY (referred_by)
REFERENCES public.users (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE SET NULL
)
TABLESPACE pg_default;
ALTER TABLE public.users
OWNER to msmf;
没有外键
// User Model. ReferredBy is self referencing Foreign Key
type User struct {
ID *int `gorm:"primaryKey; type:serial"`
Username string `gorm:"type: varchar(32) not null unique"`
Password string `gorm:"type: varchar(128) not null"`
ReferredBy *int
}
结果SQL 没有告诉 gorm 有一个外键
-- Table: public.users
-- DROP TABLE public.users;
CREATE TABLE public.users
(
id integer NOT NULL DEFAULT nextval('users_id_seq'::regclass),
username character varying(32) COLLATE pg_catalog."default" NOT NULL,
password character varying(128) COLLATE pg_catalog."default" NOT NULL,
referred_by bigint,
CONSTRAINT users_pkey PRIMARY KEY (id),
CONSTRAINT users_username_key UNIQUE (username)
)
TABLESPACE pg_default;
ALTER TABLE public.users
OWNER to msmf;
显然 type:serial
标签可以做到这一点。如果你放弃它,那么 not null 约束也不会存在:
type User struct {
ID uint `gorm:"primarykey"`
Username string `gorm:"type: varchar(32) not null unique"`
Password string `gorm:"type: varchar(128) not null"`
ReferredBy *int
Referrer *User `gorm:"foreignKey:ReferredBy;constraint:OnUpdate:CASCADE,ONDELETE:SET NULL;"`
}