We are planning to use Liquibase for SQL management for our project(Java/Oracle).
When I am trying to use the diffChangeLog command, liquibase seems to be generating 'drop table SQL' for entities that are not part of the referenceUrl passed.
However this is undesirable, as I have my entities in multiple bundles and generating diffchangeSet for one bundle is dropping tables from my other bundle and vise versa.
Any ideas how to I can configure liquibase to either use multiple referenceUrls or tell liquibase to not drop tables corresponding to my other bundle.
It sounds like your 'bundles' are all using the same database schema. If you want to have different changesets in different bundles, each will need to use a different schema. On Oracle, username and schema are closely related, so that could be part of the issue. Liquibase only works with a single schema at a time.
Related
I am developing and have made changes to a db. Before I commit I have to add the change to my change sets. So I do liquibase --url="...;name=db_dev" diff but it asks me for reference parameters. However I do not want to compare the url db with another db. I want to compare the change sets (files) with a target db.
Is this possible?
I think you may be using Liquibase in a non-standard way.
One expected usage pattern is that you create the necessary schema changes by authoring a Liquibase "change set" (in either XML, JSON, or Liquibase structured SQL) and then using liquibase update to deploy that change to each of your database instances.
A second usage pattern has you make changes directly to a database using whatever database manipulation tool you prefer, and then using liquibase diffChangelog to append the corresponding change set to your changelog file. After making the change set, you then have to use the liquibase changelogsync command to populate the Liquibase DATABASECHANGELOG table on the database with the information that the new changeset has already been 'deployed' to the database. The second usage requires that you either:
compare two live databases (for example, you could compare a 'test' or 'staging' database to whichever database you manually changed)
create a database 'snapshot' before making the manual change, then make the change, and then compare the database to the snapshot. This page on the Liquibase blog describes how to use the liquibase snapshot command to take a snapshot, and how to use that snapshot as an 'offline database' to compare to.
This page in the Liquibase documentation has some more details on usage patterns when getting started with Liquibase.
We are developing an application which uses multiple schemas to manage database objects.
I cannot see anyway of doing this with Liquibase.
I had to drop schemas manually and create them.
dropAll gradle task only drops objects in public schema.
Any help would be great.
Thanks for your time.
Liquibase can handle objects within multiple schemas and can also manage creating additional schemas as well.
When you connect to the database, Liquibase will create a DATABASECHANGELOG table in the default schema and that schema needs to exist. That table tracks which changeSets have executed, and anything that can be done through SQL can be done within your changeSets.
There are built-in tags for things like createTable, addColumn etc which will make changes in the default schema, but they all have tags such as tableSchemaName that can be used to target the object to a different schema.
If you want to make changes for which there are not built-in tags, you can always use the "sql" tag and specify whatever sql you want, such as create database additional_info
I have an existing database and have used the generateChangeLog command line to create the initial changelog. This works fine :-)
But now I want the developers to use all the tools/processes they know/use already to develop the database and code and use a script to generate any incremental change sets as appropriate.
That is: do a diff against the current state of the developer's database (url/username/password in the properties file) using the current changelog (changeLogFile in the properties file) as the base reference.
There seems no easy way to do this - the best I've come up with is:
Create a new temporary database.
Use liquibase to initialise the temp database (to what is currently in the changelog) by overriding the connection url: liquibase --url=jdbc:mysql://localhost:3306/tempbase update
Use liquibase to generate a changeset in the changelog by diff'ing the two databases:
liquibase --referenceUrl=jdbc:mysql://localhost:3306/tempbase --referenceUsername=foo --referencePassword=baz diffChangeLog
Drop the temporary database.
Synchronise the changeset: liquibase changelogSync
but there must be a better way...
You are right that liquibase cannot compare a changelog file with a database. The only real option is to compare your developer database with an actual liquibase-managed database, or at least one temporarily created.
What I would suggest as the better way is to consider shifting the developers to author liquibase changeSets in the first place. It is different tooling than they may be used to, but it has the huge advantage that they will know that the change they wanted to make is the one that will make it all the way to production. Any diff-based process (such as using diffChangeLog) will usually guess right about what changed, but not always and those differences are often not noticed until into production.
Liquibase has various features such as formatted SQL changelogs that are designed to make the transition from developers working directly against their database to tracking changes through Liquibase because once that transition is made many things get much easier.
With Liquibase Pro you can create a snapshot file that accomplishes the same thing. And then use the snapshot file to compare your database updates.
https://www.liquibase.org/documentation/snapshot.html
I mention Pro because it takes care of stored logic comparisons as well.
Flyway operates at the schema level. What about objects at the database level, e.g. roles? It seems that these database-level objects are within the scope of what an application owns and could be considered part of its deployment. Is there any way to manage these things as part of a deployment performed with Flyway?
Flyway has no technical restriction on what you can do in .sql files. As long as the command can be expressed as a sql statement, you should be fine, regardless of whether if affects a specific schema or the entire DB.
The only schema-specific thing is the clean command.
I've read about how you can generate changelog.xml from an existing schema. That's fine, but I have existing systems that I don't want to touch, except to bring in new changes. I also have completely new systems which require all changes be applied.
So, I want to get liquibase to only perform migrations from changeset X when running on an existing system. I.e. that system's DB is at revision X-1 (but no liquibase sys tables), and I don't want any preceeding migrations applied.
Many thanks,
Pat
I would recommend a slightly different approach, as commented in this Liquibase forum thread
generate a changelog from your existing schema. The liquibase CLI can do that for you. I usually take the resulting XML and smooth it out a bit (group related changes into single changelogs, do vendor-specific cleanups and so on), but Liquibase does most of the legwork.
run that changelog against the existing database (changelogSync command), but only marking it as applied (without actually modifying the schema).
use liquibase for applying new changes from that point on.
I think the easiest would be to execute the initial setup on an empty database at first and export the entry(ies) liquibase does insert into the DATABASECHANGELOG table. Then I'd export these entries and insert them manually into one of the target databases into their DATABASECHANGELOG table, so liquibase does not execute the "change" there again.
Of course I'd test all that with test dumps on a test machine... :)