Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to generate Liquibase data in the right order?

I'm using Liquibase for versioning an existing database, so I'm using

liquibase \
  --logLevel=debug \
  --driver=com.mysql.jdbc.Driver \
  --classpath=lib/mysql-connector-java-5.1.30.jar \
  --url="jdbc:mysql://127.0.0.1:3306/schema" \
  --username=user \
  --password=pass \
  --diffTypes="data" \
  --changeLogFile="./data.xml" generateChangeLog

for generating the changeset xml.

This works, but the problem is when I'm trying to run those generated changesets. I get

Cannot add or update a child row: a foreign key ...' because the exported order of changeset does not take into account the foreign keys.

My question is: Is there a command option or something that can generate the changeset in the right order or should I manually reorder the changesets to get the desired result?

Update:

Normally, the foreign keys should be and are created after the foreign key. But, in our systems, the core application creates the structure of the database and multiple client applications are populating the database with their own private data in the same database. And when we're generating the data, the data changesets are generated in the alphabetical order of the tables in the database, which may the foreign key constraints. We managed to manually arrange the changesets, but I would like to know if there is a nicer workaround for this particular situation.

like image 687
DaJackal Avatar asked May 06 '14 06:05

DaJackal


People also ask

Can Liquibase create a schema?

In Liquibase there is no "create schema" tag, because it is designed to manage objects within the application's schema. However, we can use a custom SQL statement inside a 'sql' tag to make a creation of a schema a part of our migration.

What is runOnChange Liquibase?

The runOnChange changeset attribute runs the change the first time it is detected and each time the changeset is modified. Liquibase determines that a changeset has been modified by comparing the MD5 checksum for the changeset to the checksum stored in the DATABASECHANGELOG table.

What is Databasechangelog?

Liquibase Concepts Simply put – a changelog contains an ordered list of changesets, and a changeset contains a change. You and your team can specify database changes in one of four different changelog formats: SQL, XML, JSON, or YAML. And, you can even mix and match different types of changelogs, if desired.

What is the advantage of using Liquibase?

With Liquibase, DBAs can set up quality checks for database changes that ensure developers are empowered to write database code that meets standards right from the beginning.


1 Answers

So the problem is not with the order of types of changes (tables, then data then FKs) but that you are using just the generated data insets with an existing table and FK structure? Liquibase does not even try to figure out how rows depend on each other as it gets nearly impossible in the general case.

The easiest solution is to disable FK checks before inserting and re-enable them after. How you do that depends on your database, but you can include something like:

<changeSet id="disable-keys" author="x" runAlways="true">
    <sql>SET FOREIGN_KEY_CHECKS=0;</sql>
</changeSet>

before your <insert> tags and

<changeSet id="enable-keys" author="x" runAlways="true">
    <sql>SET FOREIGN_KEY_CHECKS=1;</sql>
</changeSet>

after them.

like image 168
Nathan Voxland Avatar answered Oct 21 '22 11:10

Nathan Voxland