问题:是否可以在迁移脚本中创建一个新的db,然后连接到它?怎样?
我的场景:我尝试在我的java项目中使用flyway(restful应用程序使用jersey2.4+tomcat7+postgresql9.3.1+eclipselink)来管理使用git的不同开发人员之间的更改。我写了我的初始化脚本并运行它:
PGPASSWORD='123456' psql -U postgres -f migration/V1__initDB.sql
而且效果很好。问题是我不能用我的脚本创建新的db。当我在脚本中包含以下行时:
CREATE DATABASE my_database OWNER postgres ENCODING 'UTF8';
我得到这个错误:
org.postgresql.util.PSQLException: ERROR: CREATE DATABASE cannot run inside a transaction block
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:403)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:395)
at com.googlecode.flyway.core.dbsupport.JdbcTemplate.executeStatement(JdbcTemplate.java:230)
at com.googlecode.flyway.core.dbsupport.SqlScript.execute(SqlScript.java:89)
at com.googlecode.flyway.core.resolver.sql.SqlMigrationExecutor.execute(SqlMigrationExecutor.java:72)
at com.googlecode.flyway.core.command.DbMigrate$2.doInTransaction(DbMigrate.java:252)
at com.googlecode.flyway.core.command.DbMigrate$2.doInTransaction(DbMigrate.java:250)
at com.googlecode.flyway.core.util.jdbc.TransactionTemplate.execute(TransactionTemplate.java:56)
at com.googlecode.flyway.core.command.DbMigrate.applyMigration(DbMigrate.java:250)
at com.googlecode.flyway.core.command.DbMigrate.access$700(DbMigrate.java:47)
at com.googlecode.flyway.core.command.DbMigrate$1.doInTransaction(DbMigrate.java:189)
at com.googlecode.flyway.core.command.DbMigrate$1.doInTransaction(DbMigrate.java:138)
at com.googlecode.flyway.core.util.jdbc.TransactionTemplate.execute(TransactionTemplate.java:56)
at com.googlecode.flyway.core.command.DbMigrate.migrate(DbMigrate.java:137)
at com.googlecode.flyway.core.Flyway$1.execute(Flyway.java:872)
at com.googlecode.flyway.core.Flyway$1.execute(Flyway.java:819)
at com.googlecode.flyway.core.Flyway.execute(Flyway.java:1200)
at com.googlecode.flyway.core.Flyway.migrate(Flyway.java:819)
at ir.chom.MyApp.<init>(MyApp.java:28)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1117)
at org.jvnet.hk2.internal.Utilities.justCreate(Utilities.java:867)
at org.jvnet.hk2.internal.ServiceLocatorImpl.create(ServiceLocatorImpl.java:814)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:906)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:898)
at org.glassfish.jersey.server.ApplicationHandler.createApplication(ApplicationHandler.java:300)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:279)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:302)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:167)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:349)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1091)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5176)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5460)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3954)
at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1345)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519)
at java.lang.Thread.run(Thread.java:724)
这似乎是使用 autocommit
选项。可以通过以下方式禁用此选项:
Connection connection = dataSource.getConnection();
Connection.setAutoCommit(false); // Disables auto-commit.
但我不知道如何将此选项传递给flyway连接。另外,如果我解决了这个问题,我想我将有问题的密码传递给 \c
命令。
5条答案
按热度按时间0pizxfdo1#
flyway总是在jdbc连接字符串中使用的数据库中运行。
一旦连接,所有脚本都在事务中运行。由于事务中不支持创建数据库,您将无法完成所需的任务。
但是,您可以做的是创建一个模式。flyway甚至可以帮你,如果你指向一个不存在的。
c9qzyr3d2#
我不知道这是不是甚至可以做到在飞行方式。
flyway旨在连接到一个已经存在的数据库(不管它是否为空)。将数据库创建与数据库迁移分开也是一种很好的做法。
wqsoz72f3#
下面是一个对我有效的解决方法(假设使用maven插件):
用两次执行来配置插件。第一次执行创建数据库。第二次执行将迁移现有数据库。
然后添加
V1__Created_database.sql
到com/foo/bar/database/create
目录。此文件包含:CREATE DATABASE ${DATABASE.NAME}
kknvjkwl4#
flyway无法为您创建数据库。它可以创建一个模式,如果你没有创建一个
huwehgph5#
如果在脚本的v1中有schema database creation命令,flyway可以生成它,但不能生成数据库:
与脚本文件中的类似: