FuelPHP SimpleAuth の対象テーブルで updated_at を DATETIME 型にすると発生する SQL エラーの回避方法



前提条件

SimpleAuth

FuelPHP の Auth パッケージに附属している SimpleAuth は、データベースのテーブルを使った認証システムを構築するのに便利な機能を持っていますので、そのまま利用しているケースも多いと思います。

SimpleAuth は config/simpleauth.php で table_name に設定したテーブルを利用します。(デフォルトは "users"。)このテーブルの定義を作成するコマンドも Auth パッケージに含まれていて次のようにすることで migration ファイルが作成されます。

DATETIME 型

一方、FuelPHP のテーブル定義には created_at と updated_at という項目が含まれ、この型はデフォルトで int(11) となっています。これを MySQL の TIMESTAMPE 型、あるいは、DATETIME 型に対応させることが可能です。よく知られているように、対応するモデルの Model_Crud を継承したクラスで、 以下のようにプロパティを設定します。

このように users テーブルの created_at, updated_at を DATETIME 型に変更しても、これまでは SimpleAuth を使えていました。

MaraiDB のバージョンを上げたらエラーが発生

しかし、MaraiDB のバージョンを 10.1 系から 10.2 系に上げた際に、SimpaleAuth の create_userupdate_user で SQL のエラーが発生するようになりました。エラーの内容は次のようなものです。

‘updated_at’ は DATETIME 型なのに int(11) の値をセットしようとしてエラーとなっています。

SQL モードの確認

これは、MaraiDB を 10.2 に上げたことで、sql_mode という変数の初期値が変わったことがきっかけで出ていました。SHOW VARIABLESsql_mode の値を確認してみます。

MariaDB 10.1 (エラー無し)

SQL モードに STRICT_TRANS_TABLES は含まれていません。

MariaDB 10.2 (エラーあり)

MariaDB 10.2 の初期設定で SQLモードに STRICT_TRANS_TABLES が加わったことで、これまで UNIX タイムスタンプの int 型が自動的に DATETIME 型に置き換わっていたケースが、エラーになるようになったようです。

MariaDB 10.2 だけでなく、MySQL 5.6 でも sql_mode の初期値は STRICT_TRANS_TABLESです。

SQL モードの変更で回避

MaraiDB の設定ファイル /etc/my.cnf を編集して、sql_mode を変更します。

MariaDB サーバーを再起動すればエラーが出なくなります。なので手っ取り早く解決するにはこの方法で逃げることができます。

エラーの原因

今回のケースは SimpleAuth の中で、created_at や updated_at を int 型(UNIX タイムスタンプを保存)で決め打ちしてコーディングされていることです。

Model_Crud の場合は update_at の更新のために、以下のように $_mysql_timestamp によってセットする値を変えています。

SimpleAuth でも、同じ対応をすれば解決しそうです。

SimpleAuth の改良

対応方針としては、config/simpleauth.php に table_mysql_timestamp のような追加項目を設け(デフォルトは false)て、Model_Crud のように処理を分岐するようにします。

具体的には created_at, updated_at および last_login をセットする部分の前に

のようなコードを入れて、その値をクエリビルダーでセットするようにそれぞれ修正しました。

これで、 MariaDB サーバーの sql_mode を元通り STRICT_TRANS_TABLES に戻しても、エラーを出さないようになりました。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  • キュア子の紹介

人気記事ランキング