前人未踏の領域へ WEB・インフラ・プログラミング全般編

フロントエンド、バックエンド、インフラ、言語など、アプリ開発、IOT以外の記録

schema.rbが実行エラーになる

課題

MySQLの生成カラムを使ったテーブル定義を行ったところ、構文内に含まれる文字列が schema.rbでエスケープされ、SQL実行時にエラーとなってしまう。

やりたかったこと(例)

年と月のカラムがあるのでdate型の生成カラムを作ってみた。

ALTER TABLE t1  ADD COLUMN c1 INT 
   GENERATED ALWAYS AS (str_to_date(concat(`year`, _utf8mb3'-', `month`, _utf8mb3'-', 1), _utf8mb3'%Y-%m-%d'))

すると以下のような感じに変換される。シングルクウォートがエスケープされているのがわかる。

create_table t1 |t|
  t.virtual "c1", type: :date, as: "str_to_date(concat(`year`,_utf8mb3\\'-\\',`month`,_utf8mb3\\'-\\',1),_utf8mb3\\'%Y-%m-%d\\')"
end

まあこんな変なことしようとしているのが悪いというのは別な話であるとして。

対応

schema.rbを編集したり、生成されるクエリーをエスケープさせない対応は難しそうなので、データベーススキーマをファイルに書き出す際のフォーマットをデフォルトのRubyからSQLに変更することで対応。

#config/application.rb

class Application < Rails::Application
  config.active_record.schema_format = :sql
end

スキーマの書き出しは以下の通り。schema ではなく structure になっているのがポイント。 db/structure.sql が生成される。

db:structure:dump

schema.rbは削除してしまって問題ないだろう。

参考

blog.toshimaru.net

/* Responsive: yes */