您可以使用 Liquibase 初始化 Spring 批处理元数据表吗?
Can you initialize Spring Batch metadata tables with Liquibase?
目前我有如下设置。在 运行 在本地执行批处理作业时,作业将使用 data-source
属性 值自动创建必要的元数据表,因为 initialize-schema
设置为始终。 Liquibase 还将 运行 并创建其变更日志中列出的任何表。
这是我的 application.yml
文件
spring:
batch:
initialize-schema: always
job:
enabled: true
liquibase:
url: db_url
user: deploy_user
password: deploy_pass
change-log: classpath:db/changelog/db.changelog-master.yaml
enabled: true
data-source:
mysql:
user: r_user
password: r_pass
jdbc-url: db_url
这是我的 db.changelog-master.yaml
文件。
databaseChangeLog:
- changeSet:
dbms: mysql
id: create-sample-table
author: me
sql: CREATE TABLE sample_table (
sample_id VARCHAR(255) NOT NULL,
sample_text TEXT,
PRIMARY KEY (samoke_id)
) ENGINE=InnoDB DEFAULT
CHARSET=utf8 COLLATE=utf8_bin;
Mysql 数据源配置:
@Configuration
public class DataSourceConfiguration {
@Primary
@Bean(name = "mySQLDataSource")
@ConfigurationProperties("data-source.mysql")
public DataSource mySQLDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
}
Liquibase 配置(可能发布的内容比需要的多):
@Configuration
@EnableConfigurationProperties(LiquibaseProperties.class)
public class LiquibaseConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(LiquibaseConfiguration.class);
@Autowired
private LiquibaseProperties liquibaseProperties;
public DataSource liquibaseDataSource() {
DataSourceBuilder factory = DataSourceBuilder
.create()
.url(liquibaseProperties.getUrl())
.username(liquibaseProperties.getUser())
.password(liquibaseProperties.getPassword());
return factory.build();
}
public void testLiquibaseConnection() throws SQLException {
LOG.info("Testing connection to Liquibase (in case PCF restarts and we have stale dynamic secrets)...");
liquibaseDataSource().getConnection();
LOG.info("Testing connection to Liquibase (in case PCF restarts and we have stale dynamic secrets)... Succeeded");
}
@Bean
public SpringLiquibase liquibase() {
try {
testLiquibaseConnection();
} catch (Exception ex) {
LOG.warn("WARNING: Could not connect to the database using " + liquibaseProperties.getUser() + ", so we will be skipping the Liquibase Migration for now. ", ex);
return null;
}
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setChangeLog(this.liquibaseProperties.getChangeLog());
liquibase.setContexts(this.liquibaseProperties.getContexts());
liquibase.setDataSource(liquibaseDataSource());
liquibase.setDefaultSchema(this.liquibaseProperties.getDefaultSchema());
liquibase.setDropFirst(this.liquibaseProperties.isDropFirst());
liquibase.setShouldRun(this.liquibaseProperties.isEnabled());
liquibase.setLabels(this.liquibaseProperties.getLabels());
liquibase.setChangeLogParameters(this.liquibaseProperties.getParameters());
return liquibase;
}
}
问题是我们对 creating/deploying 表和 reading/writing 在我们部署的环境中的表有不同的凭据。因此,以下设置可以通过 Liquibase 创建表,但由于部署时的凭据不正确,因此无法创建元数据表。我们当前创建元数据表的解决方法是使用具有部署凭据的 data-source
属性进行部署,运行 初始化表的作业,然后使用 read/write 凭据重新部署。 (我们不能只留下部署凭据进行读取,因为它们的 TTL 非常短)。
是否可以通过 Liquibase 自动为 Spring Batch 创建元数据表?具体来说,没有将创建 SQL 手动添加到变更日志文件?
更新:
使用下面的 veljkost 的答案有一个看起来像这样的更新日志文件:
databaseChangeLog:
- changeSet:
dbms: mysql
id: create-spring-batch-metadata
author: dev.me
changes:
- sqlFile:
encoding: UTF-8
path: classpath:/org/springframework/batch/core/schema-mysql.sql
relativeToChangelogFile: false
splitStatements: true
stripComments: true
是的,您可以引用 Spring 批处理项目中已经存在的架构文件。在 org.springframework.batch.core
包中,您可以找到 schema-*.sql 文件,其中 * 是目标数据库的名称。由于您在 mysql 上 运行,您的更改集将如下所示:
- changeSet:
id: 1234
author: adam.sandler
changes:
- sqlFile:
encoding: utf8
path: classpath:/org/springframework/batch/core/schema-mysql.sql
relativeToChangelogFile: false
splitStatements: true
stripComments: true
在不使用 liquabase 添加的情况下自动迁移到您的数据库
spring.batch.initialize-schema=always
到您的 application.properties 文件,它将自动迁移到嵌入式数据源
目前我有如下设置。在 运行 在本地执行批处理作业时,作业将使用 data-source
属性 值自动创建必要的元数据表,因为 initialize-schema
设置为始终。 Liquibase 还将 运行 并创建其变更日志中列出的任何表。
这是我的 application.yml
文件
spring:
batch:
initialize-schema: always
job:
enabled: true
liquibase:
url: db_url
user: deploy_user
password: deploy_pass
change-log: classpath:db/changelog/db.changelog-master.yaml
enabled: true
data-source:
mysql:
user: r_user
password: r_pass
jdbc-url: db_url
这是我的 db.changelog-master.yaml
文件。
databaseChangeLog:
- changeSet:
dbms: mysql
id: create-sample-table
author: me
sql: CREATE TABLE sample_table (
sample_id VARCHAR(255) NOT NULL,
sample_text TEXT,
PRIMARY KEY (samoke_id)
) ENGINE=InnoDB DEFAULT
CHARSET=utf8 COLLATE=utf8_bin;
Mysql 数据源配置:
@Configuration
public class DataSourceConfiguration {
@Primary
@Bean(name = "mySQLDataSource")
@ConfigurationProperties("data-source.mysql")
public DataSource mySQLDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
}
Liquibase 配置(可能发布的内容比需要的多):
@Configuration
@EnableConfigurationProperties(LiquibaseProperties.class)
public class LiquibaseConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(LiquibaseConfiguration.class);
@Autowired
private LiquibaseProperties liquibaseProperties;
public DataSource liquibaseDataSource() {
DataSourceBuilder factory = DataSourceBuilder
.create()
.url(liquibaseProperties.getUrl())
.username(liquibaseProperties.getUser())
.password(liquibaseProperties.getPassword());
return factory.build();
}
public void testLiquibaseConnection() throws SQLException {
LOG.info("Testing connection to Liquibase (in case PCF restarts and we have stale dynamic secrets)...");
liquibaseDataSource().getConnection();
LOG.info("Testing connection to Liquibase (in case PCF restarts and we have stale dynamic secrets)... Succeeded");
}
@Bean
public SpringLiquibase liquibase() {
try {
testLiquibaseConnection();
} catch (Exception ex) {
LOG.warn("WARNING: Could not connect to the database using " + liquibaseProperties.getUser() + ", so we will be skipping the Liquibase Migration for now. ", ex);
return null;
}
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setChangeLog(this.liquibaseProperties.getChangeLog());
liquibase.setContexts(this.liquibaseProperties.getContexts());
liquibase.setDataSource(liquibaseDataSource());
liquibase.setDefaultSchema(this.liquibaseProperties.getDefaultSchema());
liquibase.setDropFirst(this.liquibaseProperties.isDropFirst());
liquibase.setShouldRun(this.liquibaseProperties.isEnabled());
liquibase.setLabels(this.liquibaseProperties.getLabels());
liquibase.setChangeLogParameters(this.liquibaseProperties.getParameters());
return liquibase;
}
}
问题是我们对 creating/deploying 表和 reading/writing 在我们部署的环境中的表有不同的凭据。因此,以下设置可以通过 Liquibase 创建表,但由于部署时的凭据不正确,因此无法创建元数据表。我们当前创建元数据表的解决方法是使用具有部署凭据的 data-source
属性进行部署,运行 初始化表的作业,然后使用 read/write 凭据重新部署。 (我们不能只留下部署凭据进行读取,因为它们的 TTL 非常短)。
是否可以通过 Liquibase 自动为 Spring Batch 创建元数据表?具体来说,没有将创建 SQL 手动添加到变更日志文件?
更新:
使用下面的 veljkost 的答案有一个看起来像这样的更新日志文件:
databaseChangeLog:
- changeSet:
dbms: mysql
id: create-spring-batch-metadata
author: dev.me
changes:
- sqlFile:
encoding: UTF-8
path: classpath:/org/springframework/batch/core/schema-mysql.sql
relativeToChangelogFile: false
splitStatements: true
stripComments: true
是的,您可以引用 Spring 批处理项目中已经存在的架构文件。在 org.springframework.batch.core
包中,您可以找到 schema-*.sql 文件,其中 * 是目标数据库的名称。由于您在 mysql 上 运行,您的更改集将如下所示:
- changeSet:
id: 1234
author: adam.sandler
changes:
- sqlFile:
encoding: utf8
path: classpath:/org/springframework/batch/core/schema-mysql.sql
relativeToChangelogFile: false
splitStatements: true
stripComments: true
在不使用 liquabase 添加的情况下自动迁移到您的数据库
spring.batch.initialize-schema=always
到您的 application.properties 文件,它将自动迁移到嵌入式数据源