Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop Go gorm from forcing a not null constraint on my self referencing foreign key in Postgres

I need to create a table that references itself in gorm, but cannot figure out why it is forcing a not null constraint on me. I am totally stumped. How can I get around this? I am using the AutoMigrate feature provided by gorm to create the table. The instant I remove the foreign key constraints the not null constraint goes away, but that's not what I want.

Edited: I am using the package "gorm.io/gorm" specifically, not the one on Github. This is also the only table giving me issues, any other tables which have foreign keys that reference other tables works as expected.

Go with 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
    Referrer *User `gorm:"foreignKey:ReferredBy;constraint:OnUpdate:CASCADE,ONDELETE:SET NULL"`
}

Resulting SQL with foreign key according to pgAdmin

-- 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 without foreign key

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

Resulting SQL without telling gorm there is a foreign key

-- 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;
like image 457
stew3254 Avatar asked Nov 20 '25 20:11

stew3254


1 Answers

Apparently type:serial tag does this. If you drop it the not null constraint won't be there either:

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

Reference github issue.

like image 153
joelazar Avatar answered Nov 22 '25 13:11

joelazar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!