Liquibase + MySQL + Foreign Keys to different database

Alas, my zeal was underserved :(.  Yes - it didn’t crash - and yes it generated a valid XML file.  Alas, the schema it generated the XML file was for the database referenced in the --defaultSchemaName option - ignoring the one used in the connector

I’ve created a bug in liquibase.jira.com for this issue.

Jim

I did find the --schemas option which you referenced in your original response.  There is such an option.  However, its usage is only valid on a diff - not a generate

Jim

Liquibase is really designed to only work with a single schema at a time. If you are working with complex multi-schema databases (or, as MySQL calls them, multiple databases) then you should probably look at Datical DB. The other option is to write your own wrappers around Liquibase to handle the multiple different databases. 

Steve Donie
Principal Software Engineer
Datical, Inc. http://www.datical.com/

I do tend to see generateChangeLog as a way to bootstrap using liquibase, but not the primary workflow and so there does tend to be more edge-case issues like handling cross-database foreign keys in mysql. The best way long-term to work with Liquibase is to add to the changelog file yourself during development.

However, the generateChangeLog command shouldn’t completely die in this case. There is a --schemas parameter that can be used to make Liquibase snapshot both schemas/databases which may help since it will see all the objects. Otherwise, open a but a liquibase.jira.com and I can take a look at it more.

Nathan

MySQL has a lovely feature with foreign keys.  In particular one can have a foreign key reference a table in a DIFFERENT database.  Apparently liquibase PUKES on this.  consider the following simple schema:

/*!40101 SET NAMES utf8 */;

/!40101 SET SQL_MODE=’’/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;

/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;

/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=‘NO_AUTO_VALUE_ON_ZERO’ */;

/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

CREATE DATABASE /!32312 IF NOT EXISTS/MyDB /*!40100 DEFAULT CHARACTER SET utf8 */;

USE MyDB;

DROP TABLE IF EXISTS Users;

CREATE TABLE Users (

  id INT(11) NOT NULL AUTO_INCREMENT,

  Accounts_id INT(11) DEFAULT NULL ,

  PRIMARY KEY (id),

  KEY fk_Users_Accounts_idx (Accounts_id),

  CONSTRAINT fk_Staffs_Accounts FOREIGN KEY (Accounts_id) REFERENCES AnotherDB.Accounts (id) ON DELETE CASCADE ON UPDATE CASCADE

) ENGINE=INNODB DEFAULT CHARSET=utf8 ;

If you run liquibase generateChangeLog on this schema, then it will die with the following message:

Unexpected error running Liquibase: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

Obviously my schema is much more complicated than that.  But I have reduced it to this simple problem.

Curiously on my REAL schema, I can make subtle changes to certain other aspects of the schema (e.g. rename a column in some unrelated table).  And the generateChangeLog will work!  Sort of.

Alas if you look at the output changelog file, you will discover all the tables are created with no column definitions added.  It does do other things in the resultant XML - like generated indices…But of course if you try to do something like :changeLogSync - it barfs with a bunch of errors - specifically because the columns are all null.

Any comments/suggestions from others on this bug?

Jim

Well Nathan…YOU DA’ MAN!

I suspect you didn’t exactly mean the --schemas option - I couldn’t find such an option.  However, there is the --defaultSchemaName option which DOES solve the problem.

I’m very grateful for you support and help on this issue Nathan

Jim