Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AutoMigrate with self-referential belongs to #3624

Closed
suciuvlad opened this issue Oct 17, 2020 · 4 comments
Closed

AutoMigrate with self-referential belongs to #3624

suciuvlad opened this issue Oct 17, 2020 · 4 comments
Assignees
Labels
type:question general questions

Comments

@suciuvlad
Copy link

suciuvlad commented Oct 17, 2020

Your Question

I'm trying to perform AutoMigrate on a self-referential table where the model doesn't reference the primary key:

type Transaction struct {
	gorm.Model

	ExternalID   uint `gorm:"uniqueIndex"`
	ReferenceID *uint `json:"reference_id" gorm:"uniqueIndex; type:uuid"`
	Reference   *Transaction `gorm:"foreignKey:ReferenceID; References:ExternalID"`
}

this results in the following SQL query:
CREATE TABLE "transactions" ("id" bigserial,"created_at" timestamptz,"updated_at" timestamptz,"deleted_at" timestamptz,"reference_id" bigint,"external_id" bigint,PRIMARY KEY ("id"),CONSTRAINT "fk_transactions_reference" FOREIGN KEY ("reference_id") REFERENCES "transactions"("external_id"))

that returns the following error:
"ERROR: there is no unique constraint matching given keys for referenced table "transactions" -- This is due to the fact that the constraint expects an unique index on "external_id" that is only created after CREATE TABLE query.

Expected answer

  1. Is it possible to skip creating constraints on specific columns without disabling it for all tables? (I'm aware of DisableForeignKeyConstraintWhenMigrating)
  2. Should GORM's AutoMigrate create the uniqueIndex on external_id prior to creating the constraint? (for example creating the constraint after the table's been created)

@jinzhu Any thoughts?

@suciuvlad suciuvlad added the type:question general questions label Oct 17, 2020
@jinzhu
Copy link
Member

jinzhu commented Oct 19, 2020

Is it possible to skip creating constraints on specific columns without disabling it for all tables? (I'm aware of DisableForeignKeyConstraintWhenMigrating)

Initialize another DB with DisableForeignKeyConstraintWhenMigrating when migrating the model?

Should GORM's AutoMigrate create the uniqueIndex on external_id prior to creating the constraint? (for example creating the constraint after the table's been created)

Don't think this is a good idea, and you can just set the uniqueIndex tag for the field, and use AutoMigrate to create the unique index?

@jinzhu jinzhu closed this as completed Oct 19, 2020
@suciuvlad
Copy link
Author

@jinzhu I have already set uniqueIndex on the field. But constraints are created prior to indexes during CREATE TABLE so the query to create the table fails. In this test:

func TestSelfReferentialBelongsToOverrideReferences(t *testing.T) {
type User struct {
ID int32 `gorm:"primaryKey"`
Name string
CreatedBy *int32
Creator *User `gorm:"foreignKey:CreatedBy;references:ID"`
}
checkStructRelation(t, &User{}, Relation{
Name: "Creator", Type: schema.BelongsTo, Schema: "User", FieldSchema: "User",
References: []Reference{{"ID", "User", "CreatedBy", "User", "", false}},
})
}

references:ID is set to the primary key, but if one changes it to another ID in the same table, GORM would return an error during AutoMigrate.

Here's a link to the playground: go-gorm/playground#184

@jinzhu jinzhu reopened this Oct 19, 2020
@suciuvlad suciuvlad changed the title AutoMigrate with self-referential has_one AutoMigrate with self-referential belongs to Oct 19, 2020
@jinzhu
Copy link
Member

jinzhu commented Oct 19, 2020

Hi @suciuvlad

You could use the unique tag and it creates unique constraint when creating table

type Transaction struct {
	gorm.Model

	ExternalID   uint `gorm:"unique"`
	ReferenceID *uint `json:"reference_id" gorm:"unique; type:uuid"`
	Reference   *Transaction `gorm:"foreignKey:ReferenceID; References:ExternalID"`
}

@jinzhu jinzhu closed this as completed Oct 19, 2020
@suciuvlad
Copy link
Author

@jinzhu that worked! Thank you very much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:question general questions
Projects
None yet
Development

No branches or pull requests

2 participants