Liquibase - Handling Multiple Schemas on the SQL format - liquibase

The XML format changesets allow the property of schemaName="mySchema" to indicate which schema the DDL should be executed within for a given changeset - this can then be set using properties so that the same install could be deployed on servers which use different schema names. e.g.
<createTable tableName="test" schemaName="${primarySchema}">
Using the SQL format files for Liquibase there does not seem to be any documented equivalent to the schemaName property - nor any obvious mechanism to parameterized it beyond separating out all of the DDL per schema and running the migrate command once per set of schema files.
Is there a documented / undocumented way in which to give liquibase directives in the SQL file format to handle schemas in a neater fashion such as this? (which does not work)
--changeset me:1 schemaName:mySchema

Related

Deploying to multiple schemas using Flyway

I have a question regarding Flyway and managing multiple schemas. I have multiple schemas (schema1, schema2, schema3) with different deployment schedules and different folder locations (sql/schema1, sql/schema2, sql/schema3) with different code.
I want to Flyway to create the schemas before the code deployment but how do I set this up in a single config file? I read the Flyway doc (https://flywaydb.org/documentation/faq#multiple-schemas) but is the example using a single config file? or do i need to create multiple config files (one per schema)?
Can i achieve the same setting comma delimited schema list? will "Schema1" only look in the "sql/Schema1" location? I really dont want Schema1 pulling code from a different folder i.e. sql/Schema2, etc.
Thanks in advance!
When using Flyway with multiple schemas, you need to explicitly say in the sql statements which schema the sql is going to change. You can do this by putting an ALTER SESSION SET CURRENT_SCHEMA=schema1 at the top of each migration file, or prefixing all your statements like CREATE TABLE schema1.bananas.
If this is not practical, it would be best to create a number of config files, each with a single schema specified, and a single location specified. e.g.
flyway.schemas=schema1
flyway.locations=filesystem:sql/schema1
Then you can run Flyway with each config file individually to migrate that particular schema.

Liquibase - Generating Change Logs

I want Liquibase, to generate a changelog, from this DB 'testing'. Is it possible?
I have an existing database already, with its tables and data inside.
jdbc:mysql://localhost:3306/testing
Now, I want Liquibase, to generate a changelog, from this DB 'testing'. Is it possible?
This is my command, but it doesn't work.
liquibase --driver=com.mysql.jdbc.Driver --classpath=C:\mysql-connector-java-5.1.47.jar
--changeLogFile=C:\db.changelog.xml --url="jdbc:mysql://localhost:3306/testing"
--username=root generateChangeLog
I don't use any password.
The error is related to --changeLogFile=C:\db.changelog.xml
I thought, Liquibase will refer to my DB 'testing', and generate changelog, with name 'db.changelog.xml' in folder C.
Which part I'm wrong? Do I miss something?
Or maybe, Liquibase is not intended, to generate changelog, from existing DB?
Or maybe, Liquibase is intended, to generate DB, from changelog only? And not vice versa?
This is possible. You might be having trouble since you are writing to a file in the root of your c: drive. Try c:\temp\changelog instead.
My experience is that liquibase works in increments. So if you run that command on your database, it will produce a file as if everything in the database has to be created in the changelog file (as if starting with a completely empty database).
If you read the text on Liquibase's site regarding this command, it says:
When starting to use Liquibase on an existing database, it is often useful, particularly for testing, to have a way to generate the change log to create the current database schema.
This means that if you:
Execute this command once against your dev database
Run the result against a new database (let's say test)
Run it again on your dev database
Run that file against your test database
You will get a load of errors stating that functions already exist.
I gather that the idea behind this is that you create new entries in the changelog files and executing them against ALL your databases, instead of using other tools and using liquibase for the delta.
Sample entry
<changeSet author="liquibase-docs" id="addColumn-example">
<addColumn catalogName="cat" schemaName="public" tableName="YY">
<column name="xx" type="varchar(255)"/>
</addColumn>
</changeSet>
SQL equivalent
ALTER TABLE yy ADD COLUMN xx INT

Location of Liquibase DATABASECHANGELOG Tables

I've seen how to rename the DATABASECHANGELOG tables but what I'm looking to do is to have them created in one database for each server and then deploy to the other databases on that server. We are using Liquibase on MSSQL and Sybase databases and executing via command line.
Thoughts?
I've had the same thought before as well. That's just not how it's done at my current shop :)
You're looking for these options:
--liquibaseCatalogName=<name> The name of the catalog with the
liquibase tables
--liquibaseSchemaName=<name> The name of the schema with the
liquibase tables
Doc here: http://www.liquibase.org/documentation/command_line.html.
However, --liquibaseCatalogName is not documented, but it does appear as an option when checking the command line options via liquibase --help. In your case, I believe "Catalog" equates to a Database in MSSQL and Sybase.

executing a common sql file using liquibase

I have a situation to handle, i have my liquibase structured as per the best practices recommended. I have the change log xml structured as given below
Master XML
-->Release XML
-->Feature XML
-->changelog XML
In our application group, we run updateSQL to generate the consolidated sql file and get the changes executed through our DBA group.
However, the real problem I have is to execute a common set of sql statements during every iteration. Like
ALTER SESSION SET CURRENT_SCHEMA=APPLNSCHEMA
as the DBA executes the changes as SYSTEM but the target schema is APPLNSCHEMA.
How to include such common repeating statements in Liquibase changelog.
You would be able to write an extension (http://liquibase.org/extensions) that injects it in. If you need to do it per changeLog, it may work best to extend XMLChangeLogParser to automatically create and add a new changeSet that runs the needed SQL.
You could make a changeSet with the attribute 'runAlways' set to true and include the SQL.
As far as I know, there isn't a way to have Liquibase itself do this. I suggest that you wrap Liquibase with your favorite scripting language such that you run a command "generateSQLforThoseCrazyDBAs" that runs Liquibase and then prepends the SQL you need to the output created by Liquibase.

How to generate the change log in SQL format to create the current database schema?

When starting to use Liquibase on an existing database, it is often useful, particularly for testing, to have a way to generate the change log to create the current database schema. Liquibase allows you to do this with the “generateChangeLog” command_line command. However this command will generate database change log in XML format only.
So how to generate the change log in SQL format to create the current database schema ? Does it exist any way to convert the database change log in XML format to SQL format ? If not, is there any extension point in Liquibase API to add this feature ?
There is no support currently to generate SQL, but you would be able to write an extension to do it. The *Serializer classes like liquibase.serializer.core.xml.XMLChangeLogSerializer take a changelog object and output into whatever format you want.
With something like FormattedSqlChangeLogSerializer that overrides getValidFileExtensions() to return new String[]{"xml"} you can just run generateChangeLog with outputFile=some.file.sql and get the SQL you generated in your custom serializer class.
The extension system will allow you to create this class in a custom jar.