是否可以命名 play evolution sql 脚本?
Posted
技术标签:
【中文标题】是否可以命名 play evolution sql 脚本?【英文标题】:Is it possible to name play evolution sql scripts? 【发布时间】:2017-03-29 12:23:59 【问题描述】:进化sql脚本应该命名
1.sql, 2.sql, XXX.sql根据文档。 https://www.playframework.com/documentation/2.5.x/Evolutions#Running-evolutions-using-compile-time-DI
是否有可能将命名约定更改为
1_create__customers.sql 2_create__orders.sql 3_alter__customers__add__home_address.sql喜欢它 http://edgeguides.rubyonrails.org/active_record_migrations.html#creating-a-standalone-migration
是的,我评估了https://github.com/flyway/flyway-play 我们可以切换到它。
现在我正在寻找默认播放功能。
【问题讨论】:
【参考方案1】:是的,这是可能的。
在此路径创建一个新文件:your/modules/folder/EvolutionsModule.scala
然后,添加以下内容:
package your.modules.folder
import javax.inject._
import play.api.db.evolutions._
import play.api.inject. Module
import play.api.libs.Collections
import play.api. Configuration, Environment
import org.apache.commons.io.FileUtils
class EvolutionsModule extends Module
def bindings(environment: Environment, configuration: Configuration) =
Seq(
bind[EvolutionsConfig].toProvider[DefaultEvolutionsConfigParser],
bind[EvolutionsReader].to[YourEvolutionsReader],
bind[EvolutionsApi].to[DefaultEvolutionsApi],
bind[ApplicationEvolutions].toProvider[ApplicationEvolutionsProvider].eagerly
)
@Singleton
class YourEvolutionsReader @Inject()(environment: Environment) extends EvolutionsReader
def evolutions(db: String): Seq[Evolution] =
val upsMarker = """^#.*!Ups.*$""".r
val downsMarker = """^#.*!Downs.*$""".r
val UPS = "UPS"
val DOWNS = "DOWNS"
val UNKNOWN = "UNKNOWN"
val mapUpsAndDowns: PartialFunction[String, String] =
case upsMarker() => UPS
case downsMarker() => DOWNS
case _ => UNKNOWN
val isMarker: PartialFunction[String, Boolean] =
case upsMarker() => true
case downsMarker() => true
case _ => false
val folder = environment.getFile(Evolutions.directoryName(db))
val sqlFiles = folder.listFiles()
.filter(file => file.getName.indexOf(".sql") > -1)
.sortBy(file =>
val fileName = file.getName
val nameAfterSqlNumber = fileName.split("\\.")(0).split("_").drop(1).mkString("") + ".sql"
val sqlNumber = fileName.split("\\.")(0).split("_")(0).toInt
val newPrefix = "%07d".format(sqlNumber)
newPrefix + nameAfterSqlNumber
)
.toSeq
sqlFiles.zip(1 to sqlFiles.size)
.map
case (file, revision) =>
val script = FileUtils.readFileToString(file)
val parsed = Collections.unfoldLeft(("", script.split('\n').toList.map(_.trim)))
case (_, Nil) => None
case (context, lines) =>
val (some, next) = lines.span(l => !isMarker(l))
Some((next.headOption.map(c => (mapUpsAndDowns(c), next.tail)).getOrElse("" -> Nil),
context -> some.mkString("\n")))
.reverse.drop(1).groupBy(i => i._1).mapValues _.map(_._2).mkString("\n").trim
Evolution(
revision,
parsed.getOrElse(UPS, ""),
parsed.getOrElse(DOWNS, "")
)
转到您的applications.conf
,然后添加这些行。这是为了用我们自己的替换默认的EvolutionsModule
。
play.modules
enabled += "your.modules.folder.EvolutionsModule"
disabled += "play.api.db.evolutions.EvolutionsModule"
第一段文字说明:
根据源代码,进化仅基于单个类和方法添加 -EvolutionsReader
和方法 evolutions
。
运行evolutions
方法后,evolutions 模块将依赖生成的数据库条目。所以,我们只需要用我们自己的方法覆盖这个方法。
尽管代码块很大,但实际上只是对源代码进行了少量编辑。我用 Evolutions sql 文件夹中的文件列表替换了 loadResource
函数的功能。其余部分是EvolutionsApi.scala
中evolutions
方法的直接副本
引用by this answer 的源代码很可能是实用函数——Evolutions 模块实际上并不依赖它。我找不到fileName
和resourceName
用于运行evolutions
的任何重要用法。相反,它们都引用了play_evolutions
表。
参考:https://github.com/playframework/playframework/issues/6919
【讨论】:
@Sergey 没关系。 IMO,完全放弃进化并切换是正确的决定(也放弃光滑,但这是另一回事)。但我不能,因为我正在继承一个项目。尽管如此,我还是希望这个问题能够为我和其他代码维护人员提供正确的答案,以供将来参考,尤其是因为我将长期使用 Scala。【参考方案2】:不,不可能,源码:
def fileName(db: String, revision: Int): String = s"$directoryName(db)/$revision.sql"
https://github.com/playframework/playframework/blob/2.5.x/framework/src/play-jdbc-evolutions/src/main/scala/play/api/db/evolutions/Evolutions.scala#L103
def resourceName(db: String, revision: Int): String = s"evolutions/$db/$revision.sql"
https://github.com/playframework/playframework/blob/2.5.x/framework/src/play-jdbc-evolutions/src/main/scala/play/api/db/evolutions/Evolutions.scala#L108
@Singleton
class EnvironmentEvolutionsReader @Inject() (environment: Environment) extends ResourceEvolutionsReader
def loadResource(db: String, revision: Int) =
environment.getExistingFile(Evolutions.fileName(db, revision)).map(new FileInputStream(_)).orElse
environment.resourceAsStream(Evolutions.resourceName(db, revision))
https://github.com/playframework/playframework/blob/2.5.x/framework/src/play-jdbc-evolutions/src/main/scala/play/api/db/evolutions/EvolutionsApi.scala#L471-L479
因此,正如文档中所述,您只能使用号码revision.sql
【讨论】:
以上是关于是否可以命名 play evolution sql 脚本?的主要内容,如果未能解决你的问题,请参考以下文章