Will Liquibase updateSQL command line throw error if the changeset was already applied ? - database-schema

The updateSQL liquibase command does not seem to throw an error when running updateSQL command line as it generates the relevant SQL statements for the changeset along with an entry to be created in DATABASECHANGELOG table.
My requirement is that I can only generate the SQL and hand it over to my DBA. But will liquibase throw error even if one of the changeSets in the xml fails to get created prior to generating the SQL for the changeset ?
Please help

UpdateSQL will not fail if a changeSet is already ran. The purpose of Liquibase is to track which changeSets have been applied and only "execute" changeSets that have not been ran while skipping ones that have.
If you run in regular update mode, Liquibase will directly execute each changeSet in turn. If you run in updateSql mode, Liquibase will not actually execute the SQL but instead output what it would have ran.
Liquibase will not throw any errors in updateSQL. However, if the state of the database you are going to execute the SQL file against is different than the database you run updateSQL against, the resulting SQL may not be valid. There is no re-checking of whether a changeSet has executed in the SQL output, it is just a simple "run these commands" script.

Related

Postgres alter system command fails using Hibernate fails

I want to make a change to the postgres.conf file at runtime. However, when I execute the sql with "alter system" via hibernate I get an error
Transaction is marked for rollback only or has timed out
I think this has something to do with alter system commands not allowed to execute inside a transaction block as per the documentation
Only superusers can use ALTER SYSTEM. Also, since this command acts directly on the file system and cannot be rolled back, it is not allowed inside a transaction block or function.
Im trying to understand if its possible to execute this type of command with hibernate and what I need to do to be able to do that?

Liquibase diffChangeLog command generates dropSequence changesets even if the tables are identical, what could be the issue?

I have two postgresql tables. DB_X and DB_Y which is a copy of the first. Now I've made changes to several tables in DB_Y and I wanted to migrate those changes to DB_X using liquibase diffChangeLog which results in a db-changelog.xml file.
The db-changelog file has all the changesets for the changes I made in DB_Y but additionally it has dropSequence changesets for all tables even the ones I did not change anything.
I'm running the diff command from command line. My liquibase is v3.6.2 PostgreSQL 10.2
liquibase --driver=org.postgresql.Driver --changeLogFile=D:\db-changelog14May.xml
--url="jdbc:postgresql://localhost:5432/DB_X" --username=**** --password=**** diffChangeLog
--referenceUrl="jdbc:postgresql://localhost:5432/DB_Y" --referenceUsername=***** --referencePassword=*****
I expected the the db-changelog.xml file to have only changesets for items I had changed, since I have not changed any primary keys I do not expect any sequence related changesets. What could be the issue?

Flyway doesn't mark statement in schema_version as fail in DB2

If some script fails during migration , flyway won't add record to schema_version in DB2 db for failed statement.
Do you have any idea how to avoid this situation?
I did a migration, 4th script failed, i expect this script will have status ABORTED/FAILED
One explanation for flyway behavior difference that you observe is the way Oracle handles DDL (implicit commit before/after each DDL) as compared with how Db2 handles DDL (implements DDL under transaction control by default). So with Db2 it's possible to arrange for each migration to be atomic and to rollback upon failure - meaning that there is nothing to repair, and therefore no repair action required as the flyway Oracle implementation may need.

How to recover from Entity Framework nightmare - database already has tables with the same name

How do you get EF back in Sync with code without losing data when Update-database returns the following message
Error Message: System.Data.SqlClient.SqlException (0x80131904): There
is already an object named '' in the database.
I originally wrote this as a self-answering question as I had struggled with the proble for some time, as had a few colleagues, but unfortunately, my answer was deleted and I can't recover it.
Since it's a situation that I suspect can happen several times as people try to "clean up" old migrations, I thought I'd document it with step by step instructions.
Description of the situation we found ourselves in:
We couldn't can't create a new local database because the init script was incomplete, and couldn't apply updates to the production database because the migration scripts create tables that already exist. And, we didn't want to delete production data.
Symptom: Can't run Update-Database because it's trying to run the creation script and the database already has tables with the same name.
Error Message: System.Data.SqlClient.SqlException (0x80131904): There
is already an object named '' in the database.
Problem Background:
To understand this in more detail, I'd recommend watching both videos referenced here:
https://msdn.microsoft.com/en-us/library/dn481501(v=vs.113).aspx
To summarise, EF understands where the current database is at compared to where the code is at based on a table in the database called dbo.__MigrationHistory. When it looks at the Migration Scripts, it tries to reconsile where it was last at with the scripts. If it can't, it just tries to apply them in order. This means, it goes back to the initial creation script and if you look at the very first part in the UP command, it'll be the CreeateTable for the table that the error was occurring on.
Solution: What we need to do is to trick EF into thinking that the current database is up to date, while "not" applying these CreateTable commands since the production database already exists. Once production DB is set, we still need to be able to create local databases as well.
Step 1: Production DB clean
First, make a backup of your production db. In SSMS, Right-Click on the database, Select "Tasks > Export Data-tier application..." and follow the prompts.
Open your production database and delete/drop the dbo.__MigrationHistory table.
Step 2: Local environment clean
Open your migrations folder and delete it. I'm assuming you can get this all back from git if necessary.
Step 3: Recreate Initial
In the Package Manager, run "Enable-Migrations" (EF will prompt you to use -ContextTypeName if you have multiple contexts).
Run "Add-Migration Initial -verbose". This will Create the initial script to create the database from scratch based on the current code.
If you had any seed operations in the previous Configuration.cs, then copy that across.
Step 4: Trick EF
At this point, if we ran Update-Database, we'd be getting the original error. So, we need to trick EF into thinking that it's up to date, without running these commands. So, go into the Up method in the Initial migration you just created and comment it all out.
Step 5: Update-Database
With no code to execute on the Up process, EF will create the dbo.__MigrationHistory table with the correct entry to say that it ran this script correctly. Go and check it out if you like.
Now, uncomment that code and save.
You can run Update-Database again if you want to check that EF thinks its up to date. It won't run the Up step with all of the CreateTable commands because it thinks it's already done this.
Step 6: Confirm EF is ACTUALLY up to date
If you had code that hadn't yet had migrations applied to it, this is what I did...
Run "Add-Migration MissingMigrations"
This will create practically an empty script. Because the code was there already, there was actually the correct commands to create these tables in the initial migration script, so I just cut the CreateTable and equivalent drop commands into the Up and Down methods.
Now, run Update-Database again and watch it execute your new migration script, creating the appropriate tables in the database.
Step 7: Re-confirm and commit.
Build, test, run. Ensure that everything is running then commit the changes.
Step 8: Let the rest of your team know how to proceed.
When the next person updates, EF won't know what hit it given that the scripts it had run before don't exist. But, assuming that local databases can be blown away and re-created, this is all good. They will need to drop their local database and add create it from EF again. If they had local changes and pending migrations, I'd recommend they create their DB again on master, switch to their feature branch and re-create those migration scripts from scratch.

using executable in Liquibase changesets

I am using execute command tag from my liquibase changesets and this inturn is configured to run the sqls in oracle instant client sql plus.
when i run a liquibase update on my changelogxml everything works fine and the liquibase update is sucessfull.I can see the changes to the table also.
But when i try to fail the update process by giving a syntax error in my sql file refered in the changeset.Liquibase still returns liquibase update sucessfull.I expected it to throw sql errors.The sql when run seperately in toad throws syntax error.What should i do to get the error displayed out.?
Datical has created a custom Liquibase change tag that executes SQL using the sqlplus command line client. It was surprisingly much more complicated that you might think.
Some of the issues we had to deal with:
we had to do things to ensure that the sql files always had certain statements in place, and never had certain other statements. This might include things like setting the schema, ensuring that the only spool commands were ones we knew about, that the script had an 'EXIT' command, and ensuring that whenever there was a SQL error that the exit code was returned.
The sqlplus executable does not return an exit code (i.e. a non-zero exit code form the native process) in all cases, and instead will write errors to an error table in the database. The table where sqlplus writes errors is called sperrorlog, and this may be what you will need to look into.
I can't really go into all the details, but just know that what you are attempting to do is neither simple nor straightforward.