this is my model
type Ticket struct {
gorm.Model
PassengerName string `json:"passenger_name"`
Price uint64 `json:"price"`
Seat pq.StringArray `gorm:"type:string[]" json:"seat"`
}
gorm.io/driver/postgres#v1.3.1/migrator.go:118 ERROR: type "string[]" does not exist (SQLSTATE 42704)
There’s no string data type in postgre. Change string[] to text[]
It's not a good approach. You should make a separate table for it
Ticket Table:
type Ticket struct {
gorm.Model
PassengerName string `json:"passenger_name"`
Price uint64 `json:"price"`
Seat []Seat `json:"seat" gorm:"foreignKey:SeatId"` }
Seat Table:
type Seat struct {
gorm.Modal
SeatId serial `json:seat_id`
Seat string `json:"seat"`}
Related
I have a custom JoinTable and I'm trying to get data out of it. I've tried every possible way I can imagine to get it but to no advance.
This is what I'm trying to do
type Race struct {
ID uint `gorm:"primaryKey" json:"id"`
ChampionshipId uint `gorm:"not null" json:"championshipId"`
Name string `gorm:"size:255;not null" json:"name"`
Date time.Time `gorm:"size:255;not null" json:"date"`
Finished bool `gorm:"not null" json:"finished"`
Drivers []Driver `gorm:"many2many:race_drivers;" json:"drivers"`
}
My model Race has Drivers that is an array of drivers. And this is what Driver looks like
type Driver struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"size:255;not null" json:"name"`
}
But because I need some extra data I made a custom JoinTable to add that
type RaceDriver struct {
RaceID uint `gorm:"primaryKey" json:"race_id"`
DriverID uint `gorm:"primaryKey" json:"driver_id"`
Position int `json:"position"`
Laps int `json:"points"`
}
func (driver *RaceDriver) BeforeSave(db *gorm.DB) error {
driver.Position = 0
driver.Laps = 0
return nil
}
But when calling DB.Preload("Drivers").First(&race, id) it just returns the race the ID's and Name of the drivers, not the data from the JoinTable
Also in my database setup I have the SetupJoinTable with the correct information before Automigrate
DB.SetupJoinTable(&Race{}, "Drivers", &RaceDriver{})
I've tried something like this
DB.Preload("Drivers", func(db *gorm.DB) *gorm.DB {
return db.Joins("INNER JOIN race_drivers ON race_drivers.drivers_id = drivers.id")
}).Find(&r)
which gives me this error
cannot convert 0xabec80 to Int4 SELECT * FROM "drivers" WHERE "drivers"."id" IN (1,2,3,4,5,6) AND "drivers"."id" = '0xabec80'
I switched all of my primary keys to uint64 | uint | int64 and int, they don't work.
I also tried with selects and joins without the preloading and with the preloading but that doesn't work because I try to get an array of objects.
It's kinda insane how long I've been stuck on this. Any tips would be helpfull!
I need to insert into a Postgresql database using gorm. But the struct in question has fields containing arrays of custom types:
type VideoFile struct {
UID string
FileName string
Format string
Path string
}
type myStruct struct {
ID string
UserId uint64
UserType int
FaceVideoFiles []VideoFile
MeetingVideoFiles []VideoFile
}
func (r *videoRepo) CreateRecord(input *myStruct) error {
tx := r.base.GetDB().Begin()
err := tx.Create(input).Error
if err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}
ID field is the primary key in database. I am not sure which tags to add to the struct fields so I leave it empty here (e.g. gorm:"primaryKey" json:"id", etc). If the FaceVideoFiles is not an array of struct, things seem to work, but that is not the case with an array of struct. What should I do so that I can insert those arrays of structs (not individual structs) into my database?
You have to use one to many. More information related to this. Please follow documentation. https://gorm.io/docs/has_many.html#Has-Many
type Dog struct {
ID int
Name string
Toys []Toy `gorm:"polymorphic:Owner;"`
}
type Toy struct {
ID int
Name string
OwnerID int
OwnerType string
}
db.Create(&Dog{Name: "dog1", Toys: []Toy{{Name: "toy1"}, {Name: "toy2"}}})
// INSERT INTO `dogs` (`name`) VALUES ("dog1")
// INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","dogs"), ("toy2","1","dogs")
assuming I have a model
type MyModel struct {
FirstField *CustomType `gorm:"primaryKey"`
SecondField string `gorm:"type:varchar(42)"`
}
type CustomType struct {
*big.Int
}
func (CustomType) GormDataType() string {
return "numeric"
}
Is there any way to find out through the db.DB object that the postgres type should be numeric for FirstField and varchar(42) for the SecondField?
I noticed that each field in form has a DataType that gets parsed in schema/field.go ParseField. Where is that being called and is it stored in the db somewhere? I noticed that I need a schema to call ParseField myself, but the db schema seems to be nil. Am I missing something? Thanks!
Structs
type Client struct {
Id int64
Name string
}
type Trade struct {
Id int64
ClientId int64
Client *Client
}
Query
db.Model(&Trade).Where("id = ", tradeId).Relation("Client").Select()
Error encountered: Column Id ambiguous. Not sure what's the proper way to work around this
Would be great if someone can help
You may try qualifying the Id column with either an alias or the full table name, e.g.
db.Model(&Trade).Where(`"Trade".id = ?`, tradeId).Relation("Client").Select()
type (
Id struct {
// I previously forgot to add the `ID` field in my question, it is present in my code but not on this question as #icza pointed it out to me
ID bson.ObjectId `json:"id" bson:"_id"`
}
User struct {
// When using anonymous struct, upon returning the collection, each of the document will have an empty `id` field, `id: ""`
Id
Email string `json:"email" bson:"email"`
...
}
// This works
User2 struct {
ID bson.ObjectId `json:"id" bson:"_id"`
Email string `json:"email" bson:"email"`
}
)
I might not have fully understood the concept of anonymous structs yet. In the example above, when querying all users from a collection, the id field is going to be an empty string "". However, if I directly define the ID field in the User struct, the id shows up fine. Is this not what anonymous structs are for? Basically extending struct so you won't have to type them again and again?
More example:
type SoftDelete struct {
CreatedAt time.Time `json:"created_at" bson:"created_at"`
UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
DeletedAt time.Time `json:"deleted_at" bson:"deleted_at"`
}
type UserModel struct {
SoftDelete
}
type BlogPost struct {
SoftDelete
}
The problem here is that fields having struct types (including embedded structs) appear as embedded documents in MongoDB. If you don't want this, you have to specify the "inline" bson flag when embedding a struct:
User struct {
Id `bson:",inline"`
Email string `json:"email" bson:"email"`
}
What the "inline" tag does is in MongoDB it "flattens" the fields of the embedded struct as if they were part of the embedder struct.
Similarly:
type UserModel struct {
SoftDelete `bson:",inline"`
}
type BlogPost struct {
SoftDelete `bson:",inline"`
}
Edit: the following section applies to the original Id type which embedded bson.ObjectId. The asker later clarified that this was just a typo (and edited the question since), and it is a named, non-anonymous field. Still think the info below is useful.
One thing to note about your Id type: Your Id type also embeds bson.ObjectId:
Id struct {
bson.ObjectId `json:"id" bson:"_id"`
}
Id not just has a field of bson.ObjectId, but it embeds it. This matters because this way you Id type will have a String() method promoted from bson.ObjectId, and so will User which embeds Id. Having said that, it will be hard trying to print or debug values of type User, because you will always see it printed just as a single ObjectId.
Instead you can make it a regular field in Id, embedding Id in User will still work as expected:
Id struct {
ID bson.ObjectId `json:"id" bson:"_id"`
}
See related question+asnwer: Enforce a type mapping with mgo