Liquibase - generate script without applying changesets to database

redwulf picture redwulf · Apr 8, 2014 · Viewed 11.3k times · Source

In my current project, there's a DB team that checks all the scripts before applying them to production.

We are using Liquibase to apply changesets to development, but for production, we need to be able to generate a *.sql file with all the statements.

According to the documentation of liquibase-maven-plugin, updateSQL should be what I want: http://www.liquibase.org/documentation/maven/maven_updatesql.html.

So I created two maven profiles. One to apply changes to the local development database (using liquibase:update) and one other that would just generate the script. The problem is: doing liquibase:updateSQL does generate the *.sql file (as expected), but it also tries to connect to the database and apply changes (not expected). I believe the documentation for updateSQL leads into error as it says:

Generates the SQL that is required to update the database to the current version as specified in the DatabaseChangeLogs.

Makes no mention whatsoever that it would actually apply the changesets, like liquibase:update does.

I may be missunderstanding the documentation here, but shouldn't updateSQL only generate the sql or it should actually do update + generate sql?

Here's my plugin configuration:

<plugin>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-maven-plugin</artifactId>
    <version>3.0.5</version>
    <configuration>
        <changeLogFile>src/main/resources/db/liquibase_changeset.xml</changeLogFile>
        <driver>oracle.jdbc.driver.OracleDriver</driver>
        <url>${liquibase.db.url}</url>
        <username>${liquibase.db.user}</username>
        <password>${liquibase.db.password}</password>
        <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
    </configuration>
    <executions>
        <execution>
            <phase>process-resources</phase>
            <goals>
                <goal>${liquibase.exec.goal}</goal>
            </goals>
        </execution>
    </executions>
</plugin>

And I created the profiles likes this:

<profiles>
    <profile>
        <id>local</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <liquibase.exec.goal>update</liquibase.exec.goal>
            <liquibase.exec.prompt>false</liquibase.exec.prompt>
            <liquibase.db.url>jdbc:oracle:thin:@host:1521:xe</liquibase.db.url>
            <liquibase.db.user>user</liquibase.db.user>
            <liquibase.db.password>password</liquibase.db.password>
        </properties>
    </profile>

    <profile>
        <id>uat</id>
        <properties>
            <liquibase.exec.goal>updateSQL</liquibase.exec.goal>
            <liquibase.exec.prompt>true</liquibase.exec.prompt>
            <liquibase.db.url>jdbc:oracle:thin:@host2:1521:xe</liquibase.db.url>
            <liquibase.db.user>user2</liquibase.db.user>
            <liquibase.db.password>password2</liquibase.db.password>
        </properties>
    </profile>
</profiles>

Given my maven config and my understanding, I would expect

mvn install -P uat

to only generate the script and not trying to connect to the database.

The fact that I'm forced to specify db properties (driver, etc) makes me believe that this is intended to always change database, but I suppose it should be possible to just generate the script without attempting to apply changes against a database.

Any thoughts? Is it possible but I'm completely in the wrong path? Or I'm missing some simple property? Or it's simply not supported at all?

Thanks in advance.

Answer

Nathan Voxland picture Nathan Voxland · Apr 8, 2014

UpdateSQL does not actually update the database, it just outputs SQL.

The reason it needs the database connection information and makes an actual connection because it needs to select from the databasechangelog table to determine which changeSets have been ran and which have not.