2017-05-08 13 views
2

現在、私はすべてのデータベースクエリ(主にCRUD)にGO-GORMを使用しており、生成されたUUIDをMySQLデータベース列に挿入する際に問題が発生しています。GORM UUID too too

複数のブログで提案されているように、列はBINARY(16)です.UUIDは、Golangのgithub.com/satori/go.uuidパッケージを使用して生成されます。次のように私は1つがすでにユーザーに存在しない場合はUUIDを生成するGORMのBeforeCreateフックを使用しています

は、私が使用していたコードは次のとおりです。私はまた、長さを取得するためにLENを使用している

func (u *User) BeforeCreate(scope *gorm.Scope) (err error) { 
    if u.UserID == uuid.Nil { 
     uuid, err := uuid.NewV4().MarshalBinary() 
     scope.SetColumn("user_id", uuid) 
    } 
} 

そのMarshalBinary出力し、それを返し16.

MySQLがあるに次のようにUUIDを挿入しようとしたとき、私はGORMから取得エラーなど:

(Error 1406: Data too long for column 'user_id' at row 1)

私は結果を見てもfmt.Println(UUID)を持っており、以下のように、彼らはまたある(UUIDはすべての挿入を発生させるようobviosuly変更)

[93 132 59 55 102 96 72 35 137 185 34 21 195 88 213 127]

も次のように私のMYSQLスキーマは次のとおりです。

CREATE TABLE users 
(
    id INT(10) unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT, 
    created_at TIMESTAMP, 
    updated_at TIMESTAMP, 
    deleted_at TIMESTAMP, 
    user_id BINARY(16) NOT NULL, 
    username VARCHAR(255) NOT NULL, 
    password VARCHAR(255), 
    firstname VARCHAR(255), 
    lastname VARCHAR(255), 
    email VARCHAR(255), 
    address_id VARCHAR(255) 
); 
CREATE INDEX idx_users_deleted_at ON users (deleted_at); 
CREATE UNIQUE INDEX username ON users (username); 
CREATE UNIQUE INDEX user_id ON users (user_id); 

私はUUIDを生成し、同様の結果を挿入するためにバイナリに変換するために、さまざまな方法とライブラリを試しました。

+0

おそらく愚かな質問ですが、なぜ 'user_id'にバイナリを使用していますか?どうしてあなたはhttps://en.wikipedia.org/wiki/Universally_unique_identifierのようなものを使っていますか? – pregmatch

+0

私はここでそれを生成することは本当に簡単ですhttp://stackoverflow.com/questions/15130321/is-there-a-method-to-generate-a-uuid-with-go-language見ることができます。 – pregmatch

+0

私はいつもそれを使用していますが、データベースに依存していると私は推測しています。私はあなたが 'id'と' user_id'を持っているのを見ることができます、なぜあなたは 'user_id'を持っていますか? – pregmatch

答えて

2

問題は、モデルUserの定義にあると思います。 GUIDを16バイトのバイナリとして保存するには、UserID列を[]byteではなくuuid.UUIDと定義する必要があります。

type User struct { 
    //other fields .. 
    UserID []byte 

    //other fields ... 
} 

func (u *User) BeforeCreate(scope *gorm.Scope) (err error) { 
    if u.UserID == nil { 
     uuid, err := uuid.NewV4().MarshalBinary() 
     scope.SetColumn("user_id", uuid) 
    } 
    return nil 
} 

あなたがuuid.UUIDgormは文字列としてフィールド「誤解」としてフィールドを定義し、バイナリとしてデータベースにその文字列を挿入した場合。たとえば、以下のUUID、

uuid: 16ac369b-e57f-471b-96f6-1068ead0bf98 
//16-bytes equivalent 
bytes: [22 172 54 155 229 127 71 27 150 246 16 104 234 208 191 152] 

は、このようにあなたがError 1406: ...

を取得している、長さは36バイトです

0x31 0x36 0x61 0x63 0x33 0x36 0x39 0x62 0x2D 0x65 ... 
('1' '6' 'a' 'c' '3' '6' '9' 'b' '-' 'e' ...) 

あるUUIDのASCIIコードとしてデータベースに挿入されます