【问题标题】:How do placeholders work in Flyway?占位符如何在 Flyway 中工作?
【发布时间】:2012-03-14 03:51:30
【问题描述】:

我正在评估在我的项目中使用 Flyway。我们当前的 SQL 脚本包含诸如 URL 之类的占位符,这些占位符将根据环境(dev、qa、prod)具有不同的域名。

具体来说,我们可能有类似的 INSERT 语句

INSERT INTO FEED VALUES ('app.${env.token}.company.org/feed1', 'My Feed');

${env.token} 需要替换为“dev”、“qa”或“prod”。

我们有大约 50 个不同的属性可能需要在 SQL 脚本中替换。这些属性都驻留在一个或两个属性文件中。

有没有办法运行 Flyway Ant 迁移任务,以便从属性文件中提取替换标记和值?类似于 Ant 过滤器任务的东西?

【问题讨论】:

    标签: flyway


    【解决方案1】:

    目前在提供占位符作为属性时,属性名称应以 flyway.placeholders 为前缀。

    例如,${env.token} 占位符可以直接指定为这个 Ant 属性:flyway.placeholders.env.token

    目前不支持在不使用属性名称前缀的情况下直接传递属性文件。随时在Issue Tracker 中提出问题。 :-)

    【讨论】:

    【解决方案2】:

    如果令牌是subdomain

    INSERT INTO FEED VALUES ('app.${subdomain}.company.org/feed1', 'My Feed');
    

    flyway.conf 中的值:

    flyway.url=jdbc:mydb://db
    flyway.user=root
    flyway.schemas=schema1
    flyway.placeholders.subdomain=example
    

    或命令行:

    flyway -url=jdbc:mydb://db -user=root -schemas=schema1 -placeholders.subdomain=example migrate
    

    将脚本运行为:

    INSERT INTO FEED VALUES ('app.example.company.org/feed1', 'My Feed');
    

    【讨论】:

    • 如果发现此页面的人对环境变量替换感到满意,我将使用文档页面中的此剪辑来完善您的答案:“用值 value1 替换名为 key1 的占位符,您可以将环境变量 FLYWAY_PLACEHOLDERS_KEY1 设置为 value1。然后 Flyway 会将 KEY1 部分转换为小写字母 (key1) 并在 SQL 迁移中与占位符前缀和后缀一起查找它。然后 Flyway 将替换它找到的任何匹配项值1。”
    【解决方案3】:

    根据我的经验,使用环境变量要容易得多 而不是 CLI 或配置文件(尤其是在使用 docker 和 k8s 时)。

    您可以使用以下格式的环境变量 -

    export FLYWAY_PLACEHOLDERS_USER=${USER}
    

    然后在你的sql语句中,像这样使用这个变量 -

    INSERT INTO tmptable (user)
    VALUES ('${user}')
    

    阅读更多关于环境变量的信息here

    【讨论】:

      【解决方案4】:

      Maven 版本:

      <build>
          <plugins>
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-maven-plugin</artifactId>
              </plugin>
              <plugin>
                  <groupId>org.flywaydb</groupId>
                  <artifactId>flyway-maven-plugin</artifactId>
                  <configuration>
                      <url>jdbc:mysql://localhost/cloud</url>
                      <user>root</user>
                      <password>root</password>
                      <placeholderReplacement>false</placeholderReplacement>
                  </configuration>
                  <dependencies>
                      <dependency>
                          <groupId>mysql</groupId>
                          <artifactId>mysql-connector-java</artifactId>
                          <version>${mysql.version}</version>
                          <scope>runtime</scope>
                      </dependency>
                  </dependencies>
              </plugin>
          </plugins>
      </build>
      

      【讨论】: