Hi folks,
We are writing some extensions to manage a Drupal installation from within Liquibase, with an example being enabling a Drupal module. The idea is to start with a database dump of a fresh installation and manage everything with these extensions from there.
http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/changelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd
http://www.liquibase.org/xml/ns/changelog-ext changelog-ext.xsd">
DB initialization
Enabling required modules
The problem with the code above is the extension from changeset #2 needing the dump already imported in the database to run properly. It seems like the sqlFile changes from changeset #1 are not completed when changeset #2 executions starts so enableDrupalModule fails.
It works if we perform the following steps:
- Comment changeset #2
- Run update-database
- Uncomment changeset #2
- Run update-database again
It sounds like a timing or transactional problem… any clue about what would be going on?
Thanks a lot!
Esteban
As part of changeSets finishing, liquibase will perform a commit, so I would be surprised if it was a transactional issue. What kind of database are you running against? Does the code in enableDrupalModule maybe use a connection that may have started a transaction before changeSet 1 ran? Or have cached values from before the database change?
Nathan
Hi Nathan,
Thanks a lot for your prompt response.
We are running against MySQL and enableDrupalModule runs a process from command line that asks Drupal to enable the module. Drupal will in turn update the database as part of this action. This process is invoked from the generateStatements() method as the executeCommand change does.
The enableDrupalModule just hangs if it’s ran against a Drupal without an initialized database (it happens if we create a new database and run the changelog commenting changeset #1). This is exactly what happens if we run the complete changelog against a new database too.
The funny thing are the Drupal tables (sqlFiles) not being created if we run the whole changelog (we need to ctrl+c to stop the update-database process). Shouldn’t they be created as soon as the changeset #1 is finished no matter what happens with changeset 2? Only the liquibase tables are created in the database.
Thanks again,
Esteban
BTW, is generateStatements() method being invoked for all changes in the changelog before actually executing any changeset? That would explain this behaviour. If so, is there a better place to put this logic in (I couldn’t find an alternative in the Change interface) ?
Thanks!
Esteban
OK, we could finally work around this problem. We moved the logic to a custom sql generator and it seems like the generators are only used during actual changeset execution so changeset #1 is commited when we arrive there.
Shouldn’t executeShellCommand work this way too?
Kind regards,
Esteban
You are right, generateStatements() is called several times throughout the update lifecycle (such as to determine if the change is valid for the given database). ExecuteShellCommand will need to be changed so it does not execute the command in generateStatements, but rather in a generator.
I’ll work on documenting it better.
Nathan