2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Go】gormで外部キー制約を貼れない時は、従属テーブルの型を確認する

Posted at

なにこれ

筆者がgolangとgormで遊んでる時に、数時間も↓のエラーに悩まされたため、備忘録として残します。

Error 3780: Referencing column 'book_id' and referenced column 'id' in foreign key constraint 'book_details_book_id_books_id_foreign' are incompatible.

結論

従属テーブルの型をuint型に変更すると解消する。

経緯

下記のBookテーブル(親)とBookDetailテーブル(子 or 従属)がありました。

.go
type Book struct {
	gorm.Model
	BookDetail BookDetail
}

type BookDetail struct {
	gorm.Model
	BookID      int
}

↑の状態で、gormのAddForeignKeyをやるとエラーを吐きます

migrate.go

func Migrate() {
	db.AutoMigrate(&model.Book{})
	db.CreateTable(&model.BookDetail{})
	db.Model(&model.BookDetail{}).AddForeignKey("book_id", "books(id)", "CASCADE", "CASCADE")
}

↓結果

Error 3780: Referencing column 'book_id' and referenced column 'id' in foreign key constraint 'book_details_book_id_books_id_foreign' are incompatible.

訳)エラー3780:外部キー制約「book_details_book_id_books_id_foreign」の参照列「book_id」と参照列「id」に互換性がありません。

簡単にまとめると、mysqlでIDの型が一致しない場合に起きるエラーです。

試したこと

BookDetail structBookIDの型をint型からuint型に変更しました。

.go
type BookDetail struct {
	gorm.Model
// 	BookID      int
    BookID      uint 	
}

理由

BooksテーブルのIDの型は、↓の画像の通りint unsignedになってるから。
そちらに合わせてあげれば、型が一致するので解決します。
スクリーンショット 2021-04-24 23.46.46.png

余談

unsignedとは

整数型は正の数と負の数を扱うことができますが、データ型の後に UNSIGNED を付けると 0 と正の数しか格納できなくなります。このようなデータ型を符号なし整数型といいます。

参考:整数型(TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT)

gormがuint型でIDを作成するから、それに合わせる必要があるって感じでした。

感想

Goを触り始めて2週間ほどですが、
以外にもMySQLのエラーでハマるとは思ってませんでした!
まだまだ知らないことがたくさんありました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?