Play Framework的数据库迁移方案——Evolutions
source link: https://note.qidong.name/2020/08/play-evolutions/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Play Framework的数据库迁移方案——Evolutions
2020-08-19 19:50:44 +08 字数:1704 标签: Scala
只要有个数据库,都需要迁移(Migration)方案,除非一版定稿、再不修改。
Play Framework在1.x时代,使用的是Module migrate; 而在2.x时代,使用的是Evolutions。 本文介绍Evolutions的原理与配置。
Evolutions简介 ¶
Evolutions是Play自带的一个组件,负责实现数据库Schema的变更管理。 在使用Slick的情况下,Play还需要一个额外的[play-slick-evolutions]来对接Evolutions。 [play-slick-evolutions]是play-slick的一个附带组件。
它和Module migrate比较类似,通过维护一系列的1.sql
、2.sql
等,来保留数据库Schema演进的状态。
这些SQL需要手写,并且人工确保和ORM代码保持一致。
Evolutions会根据这些SQL,提供半自动或全自动的数据库维护操作。
在数据库中,会额外多一个play_evolutions
表,记录升降级状态。
半自动操作大概是这样的:
根据提示,在开发时手动点击【Apply this script now!】,就可以执行SQL、升级数据库。 也会出现其它类型的提示,都可以根据提示来操作。
全自动操作只需要增加一行配置,见下一节。 原理大概是通过Evolutions自带的依赖注入,利用Slick完成数据库操作。
Evolutions配置 ¶
官网提供的配置,主要是针对内存数据库。 对Slick场景的Evolutions配置,语焉不详。
实际上,在build.sbt
中主要就是加两行:
libraryDependencies ++= Seq(
"com.typesafe.play" %% "play-slick" % "4.0.0",
"com.typesafe.play" %% "play-slick-evolutions" % "4.0.0",
)
这里要注意,必须把jdbc
和evolutions
删除。
前者有依赖注入的冲突,后者完全可以去掉。
虽然Play官网的2.7文档写着,上面两个依赖应该使用3.0.0
版本。
但是根据play-slick源码的README,在Slick
是3.3.1
的情况下,应该使用4.0.0
。
在build.sbt
配置完毕后,conf/application.conf
中只需要添加两行即可:
play.evolutions.enabled=true
play.evolutions.autoApply=true
第一句其实默认就是true
,但求心安。
第二句是自动升级,避免手动点击调试页面的尴尬。
如果可以,第二句最好只在生产环境的某一个服务配置,避免服务更新与动态扩容时对数据库的冲击。
SQL ¶
Evolutions的SQL,需要放置在conf/evolutions/default/
下,以1.sql
、2.sql
方式命名。
default
是数据库的默认配置名。
如果Slick配置中支持了多数据库,这里也支持按数据库名称配置多个目录的升降级SQL。
conf/evolutions/
└── default
├── 1.sql
└── 2.sql
PostgreSQL的示例如下。
1.sql
内容:
-- Users schema
-- !Ups
CREATE TABLE IF NOT EXISTS "USER" (
"id" bigserial NOT NULL PRIMARY KEY,
"email" varchar(255) NOT NULL,
"password" varchar(255) NOT NULL,
"fullname" varchar(255) NOT NULL,
"isAdmin" boolean NOT NULL
);
-- !Downs
DROP TABLE IF EXISTS "USER";
2.sql
内容:
-- Add Post and update User
-- !Ups
ALTER TABLE IF EXISTS "USER"
ADD COLUMN IF NOT EXISTS "age" int;
CREATE TABLE IF NOT EXISTS "Post" (
"id" bigserial NOT NULL PRIMARY KEY,
"title" varchar(255) NOT NULL,
"content" text NOT NULL,
"postedAt" date NOT NULL,
"author_id" bigint NOT NULL,
FOREIGN KEY ("author_id") REFERENCES "USER" ("id")
);
-- !Downs
ALTER TABLE IF EXISTS "USER"
DROP COLUMN IF EXISTS "age";
DROP TABLE IF EXISTS "Post";
其中,第一行注释是写给人看的描述,执行时无实质用途。
-- !Ups
后面是升级时执行的内容,而-- !Downs
是降级时执行的内容。
和Play 1.x时代的Module migrate相比,这种去掉create.sql
、单文件完成一次升降级的设计,更加简洁。
开发时,确保每次提交数据库Schema变更操作时,都包含对应的x.sql
文件, x
按既有次数递增。
这样,每一个数据库状态,就都被记录下来,技术上可以做到从任意版本到另一版本的升降级。
注意:这个文件中不要乱加注释,否则会影响Evolutions的解析,出现额外错误。
推荐使用pgformatter格式化。
查询升级情况 ¶
通过以下select
语句,可以在数据库中查询到Evolutions的运行结果。
# select id, hash, applied_at, state, last_problem from play_evolutions;
id | hash | applied_at | state | last_problem
----+------------------------------------------+-------------------------+---------+--------------
1 | 128a219f18c09bdee2246e68dbbd74e177d32deb | 2020-08-19 19:42:57.503 | applied |
2 | 362b9bcdc8586247f2a74917e0f6d1d41f058358 | 2020-08-19 19:42:58.134 | applied |
参考 ¶
资料比较少,除了官网,基本上只有上GitHub去看README和源码了。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK