Gormで外部キーを設定する
GOでwebアプリケーションを作ることになり、ORマッパーにgormを採用したのですが、外部キーの設定についてメモ。
Gormを利用して外部キーを設定する
外部キーを設定するにあったって下記の手順を行いました。
1. Structでデータを定義する
UserがCreditCardをHasOneで持っているAssociationを定義します。 CreditCardのUserIDがFKになる予定です。
type User struct {
gorm.Model
Name string
}
type CreditCard struct {
gorm.Model
User User
UserID int
Number string
}
この状態で、Migrateをしてみます。
db.AutoMigrate(&User{}, &CreditCard{})
実際にテーブルのindexがどうなったか確認すると。
SELECT
TABLE_NAME,
COLUMN_NAME,
CONSTRAINT_NAME,
REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = 'credit_cards'
Empty set (0.00 sec)
テーブルには外部キーが貼られてないようです。
2. AddForeignKeyを利用する
こちらのissueを見つけました。
実際にFKを貼るのであれば、AddForeignKey関数
を利用すればいいとのこと。
AddForeignKeyは下記のような引数を取ります。
func (s *DB) AddForeignKey(field string, dest string, onDelete string, onUpdate string) *DB {
・・・
}
上記を参考に、先程のmigrate処理を変更します。
db.AutoMigrate(&User{})
db.AutoMigrate(&CreditCard{}).AddForeignKey("user_id", "users(id)", "RESTRICT", "RESTRICT")`
3. Error 1215の場合はdata型が一致していないので調整する
今回の場合、credit_cardsのuser_idの型指定をunsigned intにしていなかったので、参照カラムとのデータ型違いによりError 1215で外部キーを設定できませんでした。 定義を見直し、下記のように変更して調整しました。
(int > uintに変更するだけで問題ないかもしれません)
type CreditCard struct {
gorm.Model
User User
UserID int `gorm:"type:INT(10) UNSIGNED; not null"`
Number string
}
再度マイグレーションを実行して確認すると、 問題なく貼れました!
+--------------+-------------+---------------------------------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+--------------+-------------+---------------------------------------+-----------------------+------------------------+
| credit_cards | id | PRIMARY | NULL | NULL |
| credit_cards | user_id | credit_cards_user_id_users_id_foreign | users | id |
+--------------+-------------+---------------------------------------+-----------------------+------------------------+
参考