プログラミングはじめに過去に長期インターンでRubyonRailsをやっていたのでその経験も活かして記事にしました。はてなブログ記事やりたいこと今回は自分のプロフィール(冬仕様)であるこの画像をバイナリ化してDBに保存しようと思います。Rails(RoR)を例にしてあげますが、全く理解できなくてもスルーしても読めるようにしたいとは思っています。今回使用したVersionは以下の通りです。誤字や間違いがありましたらコメントなどをいただけると幸いです。Railsはあくまでも比較のためにあるだけなので、さらっと読みたい人はGolang部分だけを見てください。文法的なことはあまり解説しませんがコンタクトしてくださればわかる範囲で答えます!実装DBこの記事では明示的にファイルを示したいのでオブジェクトをFileと名前をつけます。命名法に違和感を抱く人がいたらすみません。Railsでは以下のように書いて、ActiveRecord(Ruby製のORM)に働いてもらいます。endendなんですがupload_fileがRubyでいうbinaryでDBに書き込まれます。ORMは仲介人くらいなんでどうでもいいです。要はDBにどんなデータ型で保存されるかが重要なんです。NULLとなってました。upload_fileの方はmediumblob(8bit整数)。goでは[]byteと指定するとVARBINARYというデータ型になり、MySQLでは等価だからです。[]byteとは[]uint8のaliasです。詳しくは以下リンクで。その前に、これを実装するために、データベースを作るためのdb.goを用意しておきます。db.Close()これを以下のコマンドで実行し、データベースを作成します。最初にJPEGを画像を扱うためimage/jpegがありますが、この他に標準ではGIF,PNGに対応しています。この他の拡張子を使う場合は、他にパッケージを使うしかないようです。クラスなのでReadメソッドで読んでDBに保存すればよかったのですがGolangではどのような感じでしょう。ディレクトリ構造は以下のようになっています。実行フィアル以下にコードを示します。最終的なコードはこの記事の最後に書いています。db.Create(u)解説それではすこし解説をします。開きたい画像ファイルのパスをPATH部分にいれてos.Open(<PATH>)で開きます。問題なくいくと*os.File型の戻り値が返ってきます。}次にimage/jpegのDecodeメソッドを使ってimage.image型の変数を作ります。このimage.image型を作るかというと、あとにエンコーディングをするときに必要だからです。ここで注意したいのはかならずfile.Close()をやってください。file.Close()そしてファイルを生成してください。out.Close()をすることを忘れないでください。bytesでバッファを扱うための便利なパッケージがあります。bytes.Bufferは書き込み用のインターフェイスを持っています。newでbyte.Bufferを初期化して、imgがもつimage.image型の変数をともにjpeg.Encodeに渡しています。buffer.Bytes()json.Encodeをなぜこのようにするかというとリファレンスを読んでみたらすぐわかります。errorbyte.Bufferは書き込み用のインターフェイスio.Writerを持っているのでわたすことができます。もとの[]byte型はBytes()で取得できるのでimageBytesに変換することができます。お疲れ様でした!!終わりじゃない、、、というもの、まだ問題が残っています。それはこのままでは動かないのです。1実は今回のbinaryは長すぎるのです。いうもの、冒頭で、「VARBINARYとMIDDLEBLOBは等価だ!Rails通りだぜ!」みたいなことを書きました。ここにきて痛い目に合うのです。データの大きさが鍵となっています。余談(Blob型の歴史)もともとMySQLではバイナリ型はblob型で一括してまとめてました。バージョンが上がると、VARBINARYやVARCHARが出てきました。MySQL公式ドキュメントから参照しています。簡単な乗数の計算ですがだいたいblob型の大きさはTINYBLOB:255BBLOB:65,535BMIDDLEBLOB:16MBLONGBLOB:4GBであり、VARCHARやVARBINARYはというと255Bです。解決する話をもとに戻します。データのSizeに原因があることがわかりました。冒頭のこの部分に注目してください。足りません!LONGBLOB型が必要です。Railsのときは指摘してなかったじゃないか!と思われるかもしれませんが、その通りで、勝手にデフォルトでなっていました。3.gigabyteとして指定してすることで、今回の場合でいうとLongBlobに変更することができるのです。endend同様にgormにだってできます。gormは構造体をマッピングするという特徴があるので、構造体をいじればどうにかなりそうですよね。実際もそうで指定したいメンバにgorm:"size:70000などとしてあげるとLONGBlOBに変わります。`gorm:"size:70000"`}このようにしてSizeを変更できたので最後に実行して終わりです。main.goDBを確認すると人間には優しくない文字列がありますが、それがバイナリです。最後までお読みしてくださりありがとうございました。db.Close()}そしてrunすると実行できます。最近後輩がこの本を読んでいました。実際、python以外はプログラミングの本を読んだことがないので、そろそろ読まないとなって思います。»プロフィール学生エンジニア。忘れてしまうので備忘録です。flaskでServerlessにホストするTelepresence概論スターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。