4
3

More than 3 years have passed since last update.

PlayのEvolutionsでクエリが更新されてなくて困った時の話

Posted at

playのEvolutionsでハマったところがあったので備忘録として残しておきます。

ある日のこと

Evolutionsでテーブルを作成しようとした時の話。
以下のように1.sqlを作成し、Playを起動した。

1.sql
# --- !Ups
create table clients {
   id bigint auto_increment not null,
   name varchar(255),
   client_id varchar(255) not null,
   secret varchar(255) not null,
   email varchar(255) not null,
   user_id varchar(255) not null
}

insert into clients values (default, "Hiroro", "Hiroro0970", "hogehoge", "hiroro@exampple.com", "fuga298")
# --- !Downs
drop table clients;

しかし、画面上にはDatabase 'default' is in an inconsistentの文字が。

スクリーンショット 2019-10-08 12.40.45.png

よくみると'create table'のかっこが{}になっていたので1.sqlを以下のように修正して再起動。

1.sql
# --- !Ups
create table clients (
   id bigint auto_increment not null,
   name varchar(255),
   client_id varchar(255) not null,
   secret varchar(255) not null,
   email varchar(255) not null,
   user_id varchar(255) not null
)

insert into clients values (default, "Hiroro", "Hiroro0970", "hogehoge", "hiroro@exampple.com", "fuga298")
# --- !Downs
drop table clients;

ところが、またもや画面上にはDatabase 'default' is in an inconsistentの文字が。

スクリーンショット 2019-10-08 12.40.45.png

表示されているクエリをみると、以前のものが表示されており反映されていない様子。
キャッシュが残っているのかと思い、何度もプロジェクトをクリーン&ビルドしたが一向に直る気配がない。

エラーログをみても心当たりがないものばかり。

play.api.db.evolutions.InconsistentDatabase: Database 'default' is in an inconsistent state![An evolution has not been applied properly. Please check the problem and resolve it manually before marking it as resolved.]
    at play.api.db.evolutions.DatabaseEvolutions.$anonfun$checkEvolutionsState$3(EvolutionsApi.scala:309)
    at play.api.db.evolutions.DatabaseEvolutions.$anonfun$checkEvolutionsState$3$adapted(EvolutionsApi.scala:294)
    at play.api.db.evolutions.DatabaseEvolutions.executeQuery(EvolutionsApi.scala:341)
    at play.api.db.evolutions.DatabaseEvolutions.checkEvolutionsState(EvolutionsApi.scala:294)
    at play.api.db.evolutions.DatabaseEvolutions.evolve(EvolutionsApi.scala:263)
    at play.api.db.evolutions.DefaultEvolutionsApi.evolve(EvolutionsApi.scala:104)
    at play.api.db.evolutions.EvolutionsWebCommands.handleWebCommand(ApplicationEvolutions.scala:496)
    at play.core.DefaultWebCommands.$anonfun$handleWebCommand$1(WebCommands.scala:42)
    at scala.collection.immutable.Stream.flatMap(Stream.scala:195)
    at play.core.DefaultWebCommands.handleWebCommand(WebCommands.scala:42)

原因

ネットで検索してもなかなか解決策が見つからなかったので、ひとまずコンソールに出力されたエラーログから分析していくことにした。
すると、EvolutionsApi.scalaの293行目に
{"select id, hash, apply_script, revert_script, state, last_problem from ${schema}play_evolutions where state like 'applying_%'"
の一文を発見。

どうやら知らぬ間にデータベース内にplay_evolutionsと言うテーブルが作成されているようだ。
何が入っているのかを知るためにとりあえずMySQL(使っているDB)に接続して

select * from play_evolutions;

で中身を見てみる。
出力はこんな感じだった。

id hash applied_at apply_script revert_script state last_problem
1 ad61f40497895f0274086616dc2bc8e519244216 2019-10-07 22:43:56 create table clients { id bigint auto_increment not null, name varchar(255), client_id varchar(255) not null, secret varchar(255) not null, email varchar(255) not null, user_id varchar(255) not null } insert into clients values (default, "Hiroro", "Hiroro0970", "hogehoge", "hiroro@exampple.com", "fuga298") drop table clients applying_up You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{ id bigint auto_increment not null, name varchar(255), client_id varchar(255) n' at line 1 [ERROR:1064, SQLSTATE:42000]

apply_scriptのカラムを見てみると、そこには修正前のSQLが!?
どうやら直接1.sqlを起動しているのではなく、このテーブル内のapply_scriptに記載されているクエリを実行しているようだった。

解決方法

play_evolutions内のデータを削除して、Playを再起動してみた。
すると、クエリが更新され、修正した1.sqlが正しく実行された。

以前H2DB(in-memory)を使ってEvolutionsしていた頃は再起動かけたらきちんと動作してくれたんだけど、よく考えたらそれはin-memoryDBは文字通りインメモリだから再起動かけたらデータベース自体が全て初期化されるからだ。

MySQLとかを使うときはクエリを更新かけたらplay_evolutionsテーブルのデータを削除してから再度試してみよう。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3