Issue while creating primary key from gorm model - go

While creating primary key from gorm model it return with error “duplicate column name: “id””
my model looks like
type User struct {
gorm.Model
Id string gorm:"primary_key;"
FirstName string
LastName string
}
any idea what is the issue with above model

Gorm uses ID as the primary key by default. It is part of the gorm.Model you are embedding.
When embedding the gorm.Model, you should leave ID out as gorm already includes it. The alternative is to remove the embedded gorm.Model and specify ID yourself.
To quote the gorm conventions page:
gorm.Model is a basic GoLang struct which includes the following
fields: ID, CreatedAt, UpdatedAt, DeletedAt.
It may be embeded into your model or you may build your own model
without it.
The reasons this fails on schema creation as opposed to compilation is that a lot of databases (CockroachDB included) do case insensitive checking unless you quote the object names (Id matches id, but "Id" does not). This results in two separate column names that match when compared with case insensitivity.

Related

many to many in gorm v2 error on foreign key

I'm finding it difficult to define many to many relationship using Gorm in following cases
features(feature_id, name, slug)
operations(operation_id, name, slug)
feature_operations(feature_id, operation_id)
type Feature struct {
FeatureID int64 `gorm:"primaryKey;column:feature_id" json:"feature_id"`
Name string `validate:"required" json:"name"`
Slug string `json:"slug"`
Status string `json:"status"`
Operations []Operation `gorm:"many2many:feature_operations;foreignKey:feature_id"`
appModels.BaseModel
}
When using feature_id, I get error
column feature_operations.feature_feature_id does not exist
When using id, I get error
invalid foreign key: id
Looks like you are not using the convention that gorm suggests where you name your primary key columns just id
so in your case your foreignKey should be the name of the field and you also need to use References to specify column that you want to reference. See the example here:
https://gorm.io/docs/many_to_many.html#Override-Foreign-Key
What you need is this:
type Feature struct {
FeatureID int64 `gorm:"primaryKey;column:feature_id"`
Name string
Slug string
Operations []Operation `gorm:"many2many:feature_operations;foreignKey:FeatureID;References:OperationID"`
}
type Operation struct {
OperationID int64 `gorm:"primaryKey;column:operation_id"`
Name string
Slug string
}
After this the join table will be FEATURE_OPERATIONS with two columns FEATURE_FEATURE_ID AND OPERATION_OPERATION_ID
If you dont like the redundant column names then you need to use the two additional attributes joinForeignKey and joinReferences to choose your own names for the columns like so:
gorm:"many2many:feature_operations;foreignKey:FeatureID;joinForeignKey:FeatureID;References:OperationID;joinReferences:OperationID"
All this extra work is needed because your primary keys are FEATURE_ID and OPERATION_ID instead of just ID
If you can rename the column to follow the convention, you will notice life is much easier with gorm

GO GORM foreign key constraint is not created

I'm having issues with creating foreign key constraint for the Belongs to relationship.
A struct containing foreign key:
type Summary struct {
Id string `gorm:"primaryKey"`
OwnerId *string `gorm:"foreignKey:OwnerId references:Id;not null"`
Title string
}
Struct to which summary belongs to:
type Owner struct {
Id string `gorm:"primaryKey"`
Name string
}
It creates the tables in SQL without a problem but SQL schema doesn't contain foreign key constraint in the summary table on the owner_id column and therefore Summary can be inserted when an owner doesn't exist.
What eventually worked but not the perfect solution in my opinion is referencing the Owner struct inside Summary like so:
type Summary struct {
Id string `gorm:"primaryKey"`
OwnerId string
Owner Owner `gorm:"foreignKey:OwnerId"`
Title string
}
I wonder if it's the only way to do so
What version of gorm are you using? If you are on v1 of the library, try switching to v2. I experienced similar issues while using v1 of the library.
v1 dependency download
go get -u github.com/jinzhu/gorm
v2 dependency download
go get -u gorm.io/gorm

Is there a way to add a custom column when we create a many2many association in gorm?

I want to know 2 things
I got the following structs from a similar question.
// models/school.go
type School struct {
ID int `gorm:"primary_key"`
Name string `gorm:"not null"`
Accreditations []Accreditation `gorm:"many2many:school_accreditation;"`
}
type Accreditation struct {
// "accreditation" table
ID int `gorm:"primary_key"`
Name string
Description string
}
So, by default this will create a school_accreditation table with 2 columns:
one will have School's ID
other will have Accreditation's ID
My questions:
What is the most efficient way to add another column to the school_accreditation table?
Let's say I want to have the Name field of Accreditation in the school_accreditation table.
2.1) How do I achieve this eg: school_accreditation will have school_id, accreditation_id, accreditation_name
For the 1st question,
It seems the only way of doing it by defining the SchoolAccreditation model & adding fields to it.
Also, it gives me more control over the relationship.
For the 2nd question, I am yet to find a way if there is any!
bost
For the 2nd,
You have to manually get the name from Accreditation & then add it to the column via the defined SchoolAccreditation model.

Getting a "Duplicate column name 'id'" error when using gorm's AutoMigrate [duplicate]

While creating primary key from gorm model it return with error “duplicate column name: “id””
my model looks like
type User struct {
gorm.Model
Id string gorm:"primary_key;"
FirstName string
LastName string
}
any idea what is the issue with above model
Gorm uses ID as the primary key by default. It is part of the gorm.Model you are embedding.
When embedding the gorm.Model, you should leave ID out as gorm already includes it. The alternative is to remove the embedded gorm.Model and specify ID yourself.
To quote the gorm conventions page:
gorm.Model is a basic GoLang struct which includes the following
fields: ID, CreatedAt, UpdatedAt, DeletedAt.
It may be embeded into your model or you may build your own model
without it.
The reasons this fails on schema creation as opposed to compilation is that a lot of databases (CockroachDB included) do case insensitive checking unless you quote the object names (Id matches id, but "Id" does not). This results in two separate column names that match when compared with case insensitivity.

What is the difference between unique_index and unique?

What is the difference between unique_index and unique in GORM?
I am using MySQL 8.0, I cannot find the description about the difference between unique_index & unique form manual.
From here, see specifically the Email and MemberNumber fields:
Declaring Models
Models are usually just normal Golang structs, basic Go types, or pointers of them. sql.Scanner and driver.Valuer interfaces are also supported.
Model Example:
type User struct {
gorm.Model
Name string
Age sql.NullInt64
Birthday *time.Time
Email string `gorm:"type:varchar(100);unique_index"`
Role string `gorm:"size:255"` // set field size to 255
MemberNumber *string `gorm:"unique;not null"` // set member number to unique and not null
Num int `gorm:"AUTO_INCREMENT"` // set num to auto incrementable
Address string `gorm:"index:addr"` // create index with name `addr` for address
IgnoreMe int `gorm:"-"` // ignore this field
}
unique is a database constraint that (in this case) prevents the multiple record have the same value for MemberNumber. If such an insert or update is made, the operation will not succeed and return an error.
unique_index will create a database index that also ensures that no two values can be the same. It will do the same, but create an index.
In your case: MySQL will use a unique index behind the scenes when using a unique constraint. So when using MySQL, there is no difference when using unique and using unique index.
If you use other database management systems there might be differences.
The differences (if any) will be handled by the database management system internally. For practical purposes you can regard them as the same. The differences will be documented for each database management system.

Resources