如何防止Go的gorm在Postgres中对自我引用外键施加非空约束

3
我需要创建一个在gorm中引用自身的表,但无法理解为什么它会强制对我施加“非空”约束。我完全被卡住了。我该如何解决这个问题?我正在使用gorm提供的AutoMigrate功能来创建表。一旦删除外键约束,"非空"约束就消失了,但这不是我想要的。

编辑: 我特别使用的是"gorm.io/gorm"包,而不是Github上的那个。这也是唯一给我带来问题的表,其他引用其他表的外键的表都按预期工作。
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;

Go无外键

// 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
}

不告诉gorm有外键的情况下生成的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 bigint,
    CONSTRAINT users_pkey PRIMARY KEY (id),
    CONSTRAINT users_username_key UNIQUE (username)
)

TABLESPACE pg_default;

ALTER TABLE public.users
    OWNER to msmf;

1
它只有在自我引用时才会这样做吗? - Bohemian
是的,这是我唯一存在问题的表格。其他使用外键的表格都没有问题。 - stew3254
听起来像是一个 bug。 - Bohemian
对我来说也是这样,但我想在在他们的GitHub上发布问题之前先在这里确认一下。 - stew3254
1个回答

3

显然,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;"`
}

参考Github问题.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接