eviry tech & service blog

「株式会社エビリー」の社員ブログです。弊社では、クラウド型動画配信サービス「millvi」、ソーシャル動画データ及び分析サービス「kamui tracker」、YouTube総合メディア「かむなび」を開発・提供しています。https://eviry.com/

gormでカラムにAUTO_INCREMENTを設定したテーブルを作る時の注意点

これは旧eviry tech blogから移行した記事です。

eviry開発のtkです。

現在Goを使ったwebアプリケーションを実装しており、その中でmysqlとの連携のためにgormを使用しています。基本的な使い方は公式ドキュメントに書かれているとおりなのですが、タイトルの通りAutoMigrate関数でテーブルを作るときにAUTO_INCREMENTの属性をカラムにつけようとしてハマったので共有。

動作環境は

  • Go: 1.11.2
  • gorm: 1.9.2

AutoMigrate関数でテーブルを作った際にAUTO_INCREMENTが有効になるかどうかについて、モデル定義の記述の仕方によって以下のような違いがあります。

type Test1 struct {
    Num int `gorm:"type:int;AUTO_INCREMENT"` // NG
}

type Test2 struct {
    Num int `gorm:"AUTO_INCREMENT"` // OK
}

type Test3 struct {
    Num int `gorm:"type:int AUTO_INCREMENT"` // OK
}

試しにgormのログ設定を有効にし、発行されたクエリを確認してみます。

func main() {
    db, _ := gorm.Open("mysql", "root:root@tcp(127.0.0.1:3306)/mydb")
    defer db.Close()

    db.LogMode(true)
    db.AutoMigrate(Test1{})
    db.AutoMigrate(Test2{})
    db.AutoMigrate(Test3{})
}
[2019-01-29 16:44:36]  [32.91ms]  CREATE TABLE `test1` (`id` int , PRIMARY KEY (`id`))  
[0 rows affected or returned ] 

[2019-01-29 16:44:36]  [34.42ms]  CREATE TABLE `test2` (`id` int AUTO_INCREMENT , PRIMARY KEY (`id`))  
[0 rows affected or returned ] 

[2019-01-29 16:44:36]  [33.09ms]  CREATE TABLE `test3` (`id` int AUTO_INCREMENT , PRIMARY KEY (`id`))  
[0 rows affected or returned ] 

確かにTest1のテーブルを作成するときにはAUTO_INCREMENTが設定されておらず、それ以外の2つのテーブルでは正しく設定されています。(PRIMARY KEYも設定されていますが、これはカラム名がidなのでgormによって自動で定義されています。)

公式ドキュメントではAUTO_INCREMENTについてはほとんど触れられていませんが、githubのissueの方に今回と同じような問題が共有されており、その中で例で発生した記述方法の違いについても説明がされています。

Declaring Models | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

auto increment doesn't work · Issue #2190 · jinzhu/gorm

Unsigned int issues · Issue #201 · jinzhu/gorm

曰く、「typeを指定した上でその他のカラムの属性も設定したい時は、そのカラムの属性をすべてtypeとして書く必要がある」とのこと。上記の例で行くと、Test1はtypeとしてintしか書かれていなかったためそれ以外のカラムの設定についての記述は無視されてしまったようです。

今回はAUTO_INCREMENTで試しましたが、issueを読んでいる感じPRIMARY KEYNOT NULLも同じような扱いをする必要がありそうです。gormでカラムの設定を細かく記述する際にはご注意ください。

以上です。