go-gorm / postgres

GORM PostgreSQL driver
MIT License
225 stars 119 forks source link

postgres cannot skip foreign key creation in AutoMigrate with composite key for optional association? #234

Open mangalores opened 8 months ago

mangalores commented 8 months ago

Your Question

So I have the following base structure of two entities, that can be connected via three columns:

type BaseProduct struct {
    ID         string             `gorm:"primaryKey" json:"id"`
    Country    string             `gorm:"primaryKey;index:idx_uuid_channel_country,idx_country_productID" json:"country"`
    UUID       uuid.UUID          `gorm:"type: uuid;index:idx_uuid_channel_country;not null" json:"UUID"`
    Channel    string             `gorm:"index:idx_uuid_channel_country;not null" json:"channel"`

    Price *Price `gorm:"ForeignKey:Country,Channel,VariantUUID;References:Country,Channel,UUID" json:"price,omitempty"`
}

type Price struct {
    VariantUUID   uuid.UUID    `gorm:"uniqueIndex:idx_variant_price;type: uuid;not null" json:"variantUUID"`
    Country       string       `gorm:"uniqueIndex:idx_variant_price;not null" json:"country"`
    Channel       string       `gorm:"uniqueIndex:idx_variant_price;not null" json:"channel"`
    VolumePrice   *VolumePrice `gorm:"type: JSONB" json:"volumePrice,omitempty"`
    Price         float32      `gorm:"type: NUMERIC(10, 2)" json:"price" validate:"omitempty,min=0"`

    Products []*BaseProduct `gorm:"References:Country,Channel,VariantUUID;ForeignKey:Country,Channel,UUID" json:"variants,omitempty"`
}

both entities get updated in different streams and product becomes valid when price is there and so on. This is solved application side in the further processing pipeline.

Obviously this is an optional association that does not have to be there.

Result

This setup works in use. Price is optionally loaded when it is there, otherwise nil.

However AutoMigrate fails on existing data. Gorm tries to generate a foreign key restraint. However as the relation is optional not all entries have a matching entry, but due to unique key composition in each table the postgres constraint implicitly is a hard dependency which then fails on the data because none of the columns can be null in either table.

Expected answer

Is there a way to modify the foreign key creation for postgres or suppress creating a hard database constraint in the auto migration for postgres?

Probably I simply would like to have the association, but not have AutoMigrate generate a constraint.

iTanken commented 8 months ago

https://gorm.io/docs/gorm_config.html#DisableForeignKeyConstraintWhenMigrating

Have you tried setting DisableForeignKeyConstraintWhenMigrating to true when opening the connection?