MySQL says "Cannot add foreign key constraint" when execute sql generated with MySQL Workbench

MySQL Workbenchで生成したSQLがなぜか実行時に"Cannot add foreign key constraint"と言われてしまい失敗するという話です。

ER図上で、外部キー制約を付けた二つのカラムの型が異なっていたために生じていました。例えば、 INTVARCHAR(45) といった形です。

修正したら首尾よく実行されました。

参考:MySQL Workbench Forward Engineer Error 1215: Cannot add foreign key constraint

CreationException: Unable to create injector

原因:jdbcとplay-slickが依存性に含まれていると、それぞれがplay.api.db.DBApiを使用するので、競合してエラーとなる。

対策:jdbcの除去

参考:play-framework > [play 2.4.0-RC5 Scala] evolutions and injector error with play-slick

! @6mk485065 - Internal server error, for (GET) [/] ->

play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:

1) A binding to play.api.db.DBApi was already configured at play.api.db.slick.evolutions.EvolutionsModule.bindings(EvolutionsModule.scala:14):
Binding(interface play.api.db.DBApi to ConstructionTarget(class play.api.db.slick.evolutions.internal.DBApiAdapter) in interface javax.inject.Singleton) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1).
  at play.api.db.DBModule.bindings(DBModule.scala:25):
Binding(interface play.api.db.DBApi to ProviderConstructionTarget(class play.api.db.DBApiProvider)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)

1 error]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:165) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at scala.Option.map(Option.scala:146) ~[scala-library-2.11.6.jar:na]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:119) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at scala.util.Success.flatMap(Try.scala:230) ~[scala-library-2.11.6.jar:na]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:119) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:111) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) ~[scala-library-2.11.6.jar:na]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[scala-library-2.11.6.jar:na]
    at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1423) ~[na:1.8.0_05]
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) ~[na:1.8.0_05]
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:902) ~[na:1.8.0_05]
    at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1689) ~[na:1.8.0_05]
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1644) ~[na:1.8.0_05]
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) ~[na:1.8.0_05]
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:

1) A binding to play.api.db.DBApi was already configured at play.api.db.slick.evolutions.EvolutionsModule.bindings(EvolutionsModule.scala:14):
Binding(interface play.api.db.DBApi to ConstructionTarget(class play.api.db.slick.evolutions.internal.DBApiAdapter) in interface javax.inject.Singleton) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1).
  at play.api.db.DBModule.bindings(DBModule.scala:25):
Binding(interface play.api.db.DBApi to ProviderConstructionTarget(class play.api.db.DBApiProvider)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)

1 error
    at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107) ~[guice-4.0.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:96) ~[guice-4.0.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:73) ~[guice-4.0.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:62) ~[guice-4.0.jar:na]
    at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:126) ~[play_2.11-2.4.1.jar:2.4.1]
    at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:93) ~[play_2.11-2.4.1.jar:2.4.1]
    at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21) ~[play_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:153) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:150) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21) ~[play_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:150) ~[play-server_2.11-2.4.1.jar:2.4.1]
    ... 15 common frames omitted

Crashlytics Invocation Error

チームメンバーがCrashlyticsをインストールしてくれたのだが、ビルドに失敗したので、どうすればいいのか調べた。

エラーメッセージはこちら

Shell Script Invocation Error
Command /bin/sh failed with exit code 1
Crashlytics: You must install Crashlytics to continue. https://api.crashlytics.com/api/v1/******************/confirm/jp.app.appName

If this machine is a build server please remove Crashlytics.app if present and use xcodebuild so that ukissAlarm.app.dSYM is uploaded.

解決方法は単純で、Crashlyticsのビルドツールをインストールしていなかったことが原因であった。

https://crashlytics.com/downloads

Crashlyticsはなかなか良いツールだけれど、導入方法の説明ページを見つけづらくて参った。Qiita等を見てやっと解決に辿り着いた。


Crash Report解析サービスのCrashlyticsを試してみた

今回の不正解ルート
パーミッションの変更:iOS xcode 5 crashlytics error - Shell Script Invocation Error - ./Crashlytics.framework/run: Permission denied

試していないもの
Crashlytics.appを一旦削除:Crashlytics build script fails on Xcode Server CI

Scala: ファイルの内容を一行ずつ処理したい

java.nio.file.Filesで一行ごとに処理(ただしScala)

Java SE 7のjava.nio.file.Filesがとても便利な件

ファイルの内容を一行ずつ読み込んで処理したい場合に、今まではこちらのページ:(Fileの読み込み - Scala覚書)を参考に実装していましたが、nioを使えば簡単だったので、メモしておきます。

val file = Paths.get(path)
Files.readAllLines(file, Charset.defaultCharset())
     .foreach(println)

Charset.defaultCharset()が鬱陶しいですがそれに目を瞑ればシンプルです。 scala.io.Sourcejava.io.BufferedReadercommons.io.FileUtils だといずれもバッファをクローズする必要があるので、それに比べればだいぶ良いのではないでしょうか。

巨大なファイルのとき

これは、scala.io.Sourceを利用するのがよさそう。構造的部分型を利用したローンパターンを使わなければならないので、そのぶんコードが膨らみますが、そのぶん使用箇所はシンプルにまとまります。

using(Source.fromFile("file.txt")) {
     _.getLines().foreach(println)
}

def using[A <% { def close():Unit }](s: A)(f: A=>Any) {
     try f(s) finally s.close()
}

また、using内でSourceのもつメソッドを十分に活用したい場合は、構造的部分型での一般化を諦める必要があります。
参考:Scala using(ローンパターン)-Hishidama's Scala Memo-