How do I migrate an existing production database with Liquibase and JHipster? - postgresql

I'm trying to update my 21-points.com app to use the latest code from the JHipster Mini-Book. Here’s what I’ve done so far:
Use Heroku’s pg:pull command to copy my production database to a local database:
heroku pg:pull HEROKU_POSTGRESQL_GRAY_URL health --app health-by-points
Installed Liquibase and copied the PostgreSQL database driver into $LIQUIBASE_HOME/lib.
[mraible:/opt/tools/liquibase-3.5.3-bin] % cp ~/.m2/repository/org/postgresql/postgresql/9.4.1212/postgresql-9.4.1212.jar lib/.
Ran liquibase’s “diffChangeLog” to generate a changelog to migrate from old database to new schema.
./liquibase \
--driver=org.postgresql.Driver --url=jdbc:postgresql://localhost:5432/health --username=postgres \
diffChangeLog \
--referenceUrl=jdbc:postgresql://localhost:5432/twentyonepoints \
--referenceUsername=twentyonepoints --referencePassword=21points
Copied output to src/main/resources/config/liquibase/changelog/20171024115100_migrate_from_v2.xml and added to config/liquibase/master.xml.
Changed application-prod.xml in my latest-and-greatest JHipster app to point to old database that I downloaded from Heroku.
Ran ./gradlew -Pprod. Error on startup:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [org/jhipster/health/config/DatabaseConfiguration.class]: Invocation of init method failed; nested exception is liquibase.exception.ValidationFailedException: Validation Failed:
2 change sets check sum
config/liquibase/changelog/00000000000000_initial_schema.xml::00000000000000::jhipster was: 7:eda8cd7fd15284e6128be97bd8edea82 but is now: 7:a6235f40597a13436aa36c6d61db2269
config/liquibase/changelog/00000000000000_initial_schema.xml::00000000000001::jhipster was: 7:e87abbb935c561251405aea5c91bc3a4 but is now: 7:29cf7a7467c2961e7a2366c4347704d7
Ran the following commands to update the md5sum’s in the database.
update databasechangelog set md5sum = '7:a6235f40597a13436aa36c6d61db2269' where md5sum = '7:eda8cd7fd15284e6128be97bd8edea82';
update databasechangelog set md5sum = '7:29cf7a7467c2961e7a2366c4347704d7' where md5sum = '7:e87abbb935c561251405aea5c91bc3a4’;
Tried to run again.
2017-10-24 12:12:02.670 ERROR 22960 --- [ main] liquibase : classpath:config/liquibase/master.xml: config/liquibase/changelog/20160831020048_added_entity_Points.xml::20160831020048-1::jhipster: Change Set config/liquibase/changelog/20160831020048_added_entity_Points.xml::20160831020048-1::jhipster failed. Error: ERROR: relation "points" already exists [Failed SQL: CREATE TABLE public.points (id BIGINT NOT NULL, jhi_date date NOT NULL, exercise INT, meals INT, alcohol INT, notes VARCHAR(140), user_id BIGINT, CONSTRAINT PK_POINTS PRIMARY KEY (id))]
2017-10-24 12:12:02.672 WARN 22960 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [org/jhipster/health/config/DatabaseConfiguration.class]: Invocation of init method failed; nested exception is liquibase.exception.MigrationFailedException: Migration failed for change set config/liquibase/changelog/20160831020048_added_entity_Points.xml::20160831020048-1::jhipster:
Reason: liquibase.exception.DatabaseException: ERROR: relation "points" already exists [Failed SQL: CREATE TABLE public.points (id BIGINT NOT NULL, jhi_date date NOT NULL, exercise INT, meals INT, alcohol INT, notes VARCHAR(140), user_id BIGINT, CONSTRAINT PK_POINTS PRIMARY KEY (id))]
Any idea why it’s trying to create my database tables again? Is it because I changed the md5sum?
Do these look like the proper steps you’d take when migrating from an old JHipster-generated schema to a brand new one? The only difference between my old schema and new one is the old one has a preferences_id column in the user table while the new one has a user_id column in the preferences table.

I would do almost the same: on step 7 I wold relay on liquibase methods for working with the checksum, i.e. I would use clearCheckSums from command line and then on next run all the checksums are gone be recomputed and if there still is an error about a script that wants to run again like in step 8 then you can use changelogSync from command line like:
./liquibase --driver=org.postgresql.Driver --url=jdbc:postgresql://localhost:5432/health
--username=postgres clearCheckSums
./liquibase --driver=org.postgresql.Driver --url=jdbc:postgresql://localhost:5432/health
--username=postgres changelogSync

Related

Liquibase Validation Failed Exception - change sets check sum

After launch the application, I get an error:
Caused by: liquibase.exception.ValidationFailedException: Validation Failed: 1 change sets checksum was: 8:2b2936713e8d9aea052c3122fd81faec but now it is:
8:ed8f7550fdd9809f4f6bf0f2d83dbbd8
The error points to such a table:
create table car (
id bigint not null auto_increment PRIMARY KEY,
name varchar(255) not null,
category varchar(255) not null
);
I read about this error and it was pointed out to use the mvn liquibase:clearCheckSums command but in the terminal I get the error: Error: -classpath requires class path specification (I run the command in the project folder)
The error indicates that a changelog that already run now is running with some changes. If you change something on an already run changelog then the checksum changes and this error is completely normal.
Check your databasechangelog table for the mentioned checksum to verify the changelog that crashes. The solutions are usually not to change the checksum of an already run changelog. If you can drop this changelog from the database and run it again will work fine. Sometimes the same changelog crashes without changing anything. This happening to me all the time because of the line seperator. For example, on IntleliJ you can change it from here:
Check what line separator do you need by testing :)

Keycloak 18 won't create default-tables on docker when configure a second DB via quarkus.properties

I am implementing a Custom Userprovider SPI for keycloak 18.0.2 and therefore have (alongside the keycloak default PostgreSQL-DB) a MSSQL in use.
The customized Keycloak and the PostgreSQL are run via docker-container.
The problems occure on my local MacBook M1 (but the same behaviour on intel-cpu as well). When building and starting the custom keycloak container, all volumes for both containers are removed. So there is always fresh DB-container
(sidenote: As the SPI was written for WildFly and it is broken with 19.x.x, i just stepped back to 18.0.2 to get the whole process working again. Afterwards will update to 19 and adapt the SPI implementations.)
the problem ...
Keycloak will create all tables - for the default keycloak-db (PostgreSQL) - in the public schema ONLY IF i configure the connection to the MSSQL via persistence.xml. This must not be in the production setup, as this should be at least configurable by the gitlab pipeline.
If i move the connection-infos from persistence.xml to quarkus.properties (as described in here: https://github.com/keycloak/keycloak-quickstarts/tree/main/user-storage-jpa), the default DB-tables can't be created anymore...
logs in Postgre-Container:
LOG: database system is ready to accept connections
ERROR: relation "migration_model" does not exist at character 25
STATEMENT: SELECT ID, VERSION FROM MIGRATION_MODEL ORDER BY UPDATE_TIME DESC
ERROR: syntax error at end of input at character 20
STATEMENT: call current_schema
ERROR: current transaction is aborted, commands ignored until end of transaction block
STATEMENT: SELECT COUNT(*) FROM DATABASECHANGELOG
ERROR: syntax error at end of input at character 20
STATEMENT: call current_schema
ERROR: current transaction is aborted, commands ignored until end of transaction block
STATEMENT: SELECT COUNT(*) FROM DATABASECHANGELOGLOCK
ERROR: syntax error at end of input at character 20
STATEMENT: call current_schema
ERROR: current transaction is aborted, commands ignored until end of transaction block
STATEMENT: CREATE TABLE DATABASECHANGELOGLOCK (ID INT NOT NULL, "LOCKED" BOOLEAN NOT NULL, LOCKGRANTED datetime, LOCKEDBY VARCHAR(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID))
ERROR: syntax error at end of input at character 20
keycloak logs:
WARN [liquibase.database.DatabaseFactory] (main) Unknown database: PostgreSQL
WARN [org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockService] (main) Failed to create lock table. Maybe other transaction created in the meantime. Retrying...
ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: Failed to start server in (development) mode
Does using the quarkus.properties overwrite some keycloak-defaults? so, when using it, keycloak acts differently than the configuration without a custom quarkus file?

Why is liquibase deleting databasechangelog rows and trying to create a renamed database table?

I am using postgres 10.5 and liquibase 3.6.2 on a Mac.
I nuke & re-create my database, run liquibase update, and it works.
But a second liquibase update fails with an exception that the pkey already exists.
After the first liquibase update, the databasechangelog table contains 97 entries. After the second, it contains 10, and the time and deployment ids for those are different than they were after the first update!
Table foo was created in an early change.
Later it was changed to be named bar, but the pkey is still foo.pkey.
Liquibase-update should not be trying to re-create foo, but it does, and fails because foo.pkey already exists.
A) In general, how can I get liquibase to output more info about what it's doing? I tried both of the commands:
liquibase --logLevel=debug --logFile=`pwd`/foo.log update
liquibase --logLevel debug --logFile `pwd`/foo.log update
Both seem to work the same, and foo.log isn't created and there's no more output in the terminal.
B) How can I stop liquibase from trying to re-make this and nuking my databasechangelog?
I tried to make a small example that fails, but this seems to work... Others here are using it with postgres 9.5.10 with no problem...
All I see in the terminal is:
Starting Liquibase at Wed, 14 Nov 2018 13:06:44 PST (version 3.6.2 built at 2018-07-03 11:28:09)
Unexpected error running Liquibase: ERROR: relation "cant_change_pkey" already exists [Failed SQL: CREATE TABLE nuss.cant_change (message_id UUID NOT NULL, origin VARCHAR(4), type VARCHAR(12) NOT NULL, CONSTRAINT CANT_CHANGE_PKEY PRIMARY KEY (message_id), UNIQUE (message_id))]
liquibase.exception.MigrationFailedException: Migration failed for change set db/changelog/changelog-new1.xml::first-one::rstrauss:
Reason: liquibase.exception.DatabaseException: ERROR: relation "cant_change_pkey" already exists [Failed SQL: CREATE TABLE nuss.cant_change (message_id UUID NOT NULL, origin VARCHAR(4), type VARCHAR(12) NOT NULL, CONSTRAINT CANT_CHANGE_PKEY PRIMARY KEY (message_id), UNIQUE (message_id))]
at liquibase.changelog.ChangeSet.execute(ChangeSet.java:637)
at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:53)
at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:78)
at liquibase.Liquibase.update(Liquibase.java:202)
at liquibase.Liquibase.update(Liquibase.java:179)
at liquibase.integration.commandline.Main.doMigration(Main.java:1205)
at liquibase.integration.commandline.Main.run(Main.java:191)
at liquibase.integration.commandline.Main.main(Main.java:129)
Caused by: liquibase.exception.DatabaseException: ERROR: relation "cant_change_pkey" already exists [Failed SQL: CREATE TABLE nuss.cant_change (message_id UUID NOT NULL, origin VARCHAR(4), type VARCHAR(12) NOT NULL, CONSTRAINT CANT_CHANGE_PKEY PRIMARY KEY (message_id), UNIQUE (message_id))]
at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:356)
at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:57)
at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:125)
at liquibase.database.AbstractJdbcDatabase.execute(AbstractJdbcDatabase.java:1229)
at liquibase.database.AbstractJdbcDatabase.executeStatements(AbstractJdbcDatabase.java:1211)
at liquibase.changelog.ChangeSet.execute(ChangeSet.java:600)
... 7 common frames omitted
Caused by: org.postgresql.util.PSQLException: ERROR: relation "cant_change_pkey" already exists
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2476)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2189)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:300)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:428)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:354)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:301)
at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:287)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:264)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:260)
at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:352)
... 12 common frames omitted
For more information, please use the --logLevel flag

Spring Boot 2 - H2 Database - #SpringBootTest - Failing on org.h2.jdbc.JdbcSQLException: Table already exists

Unable to test Spring Boot & H2 with a script for creation of table using schema.sql.
So, what’s happening is that I have the following properties set:
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.initialization-mode=always
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.platform=h2
spring.datasource.url=jdbc:h2:mem:city;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.generate-ddl=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
and, I expect the tables to be created using the schema.sql. The application works fine when I run gradle bootRun. However, when I run tests using gradle test, my tests for Repository passes, but the one for my Service fails stating that it’s trying to create the table when the table already exists:
Exception raised:
Caused by: org.h2.jdbc.JdbcSQLException: Table "CITY" already exists;
SQL statement:
CREATE TABLE city ( id BIGINT NOT NULL, country VARCHAR(255) NOT NULL, map VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, state VARCHAR(2555) NOT NULL, PRIMARY KEY (id) ) [42101-196]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.command.ddl.CreateTable.update(CreateTable.java:117)
at org.h2.command.CommandContainer.update(CommandContainer.java:101)
at org.h2.command.Command.executeUpdate(Command.java:260)
at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:192)
at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:164)
at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95)
at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java)
at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:471)
... 105 more
The code is setup and ready to recreate the scenario. README has all the information ->
https://github.com/tekpartner/learn-spring-boot-data-jpa-h2
If the tests are run individually, they pass. I think the problem is due to schema.sql being executed twice against the same database. It fails the second time as the tables already exist.
As a workaround, you could set spring.datasource.continue-on-error=true in application.properties.
Another option is to add the #AutoConfigureTestDatabase annotation where appropriate so that a unique embedded database is used for each test.
There are 2 other possible solutions you could try:
Add a drop table if exists [tablename] in your schema.sql before you create the table.
Change the statement from CREATE TABLE to CREATE TABLE IF NOT EXISTS

Is there any way to skip migrations which are failing?

I want to run migration on my server for ruby on rails project but I am getting this kind of error with postgres-
PGError: ERROR: relation "last_message_read" already exists
: CREATE TABLE "last_message_read" ("id" serial primary key, "message" character varying(255), "company_id" integer)
So, I want to continue with my migration but it is not happening - I want to ignore those migration which are failing and continue with the rest....
Something's wrong with your migrations. Just reset your db (rake db:reset).