How to force dialect in Flyway test extensions? - mysql

I'm using Flyway test extensions with H2 database and MySQL dialect.
Unfortunately, #FlywayTest annotation executes database clean with H2 dialect and ends with error:
org.flywaydb.core.internal.dbsupport.FlywaySqlException:
Unable to drop "PUBLIC"."site"
------------------------------
SQL State : 42S02
Error Code : 42102
Message : Table "site" not found; SQL statement:
DROP TABLE "PUBLIC"."site" CASCADE [42102-193]
at org.flywaydb.core.internal.dbsupport.SchemaObject.drop(SchemaObject.java:82)
at org.flywaydb.core.internal.dbsupport.h2.H2Schema.doClean(H2Schema.java:69)
at org.flywaydb.core.internal.dbsupport.Schema.clean(Schema.java:148)
at org.flywaydb.core.internal.command.DbClean$4.call(DbClean.java:184)
at org.flywaydb.core.internal.command.DbClean$4.call(DbClean.java:181)
at org.flywaydb.core.internal.util.jdbc.TransactionTemplate.exec
However, when I manually run DROP TABLE PUBLIC.site CASCADE (no quotes) from console it ends successfully.
How to force dialect in Flyway test extensions?

This is no problem of the annotation #FlywayTest.
The annotation #FlywayTest call flyway.clean() method.
And Flyway supports for H2 only quoted names for schema and tables.
See class source code on Github https://github.com/flyway/flyway/blob/master/flyway-core/src/main/java/org/flywaydb/core/internal/dbsupport/h2/
I think there will be no plan to support H2 feature modes, such like Mysql, Oracle, ....
You can open a issue here https://github.com/flyway/flyway/issues

Related

Spring Boot & Hibernate: MySQL TEXT with local h2 and Flyway

I am building a Spring Boot application which has several long texts in it's entities.
To ensure I can handle my database migrations well I included Flyway. In production I'm using a MySQL database, for local testing I want to implement the default h2 database.
An entity might have the following property
#Column(columnDefinition = "TEXT")
val startText: String?
For my MySQL database, this works fine and looks like this in my flyway schema:
start_text TEXT,
When I now start my tests with the default h2 in-memory database in Spring, I receive the following error:
Schema-validation: wrong column type encountered in column [start_text] in table [t_table]; found [clob (Types#CLOB)], but expecting [text (Types#VARCHAR)]
I understand that h2 does not support the MySQL specific type TEXT but actually I have no clue how to fix this.
Any help is appreciated.
Thank you.
I found a workaround for this.
In my application.yaml I have the following:
spring:
flyway:
placeholders:
text-datatype: 'TEXT' #defines a placeholder that is available in flyway
In my application.yaml in my test folder I have the following
spring:
flyway:
placeholders:
text-datatype: 'VARCHAR(255)'
Now I can use the placeholder in my Flyway scripts and it works fine:
start_text ${text-datatype}

For django testing, how do I use keepdb with mariadb

I have a database with a lot of nonmanaged tables which I'm using for a django app. For testing I'm wanting to use the --keepdb option so that I don't have to repopulate these tables every time. I'm using MariaDB for my database. If I don't use the keepdb option everything works fine, the test database gets created and destroyed properly.
But when I try to run the test keeping the database:
$ python manage.py test --keepdb
I get the following error:
Using existing test database for alias 'default'...
Got an error creating the test database: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CREATE DATABASE IF NOT EXISTS test_livedb ;\n SET sql_note' at line 2")
I assume that this is an issue with a different syntax between MariaDB and MySQL. Is there anyway to get the keepdb option to work with MariaDB?
thanks very much!
For what it's worth: This bug was introduced in Django 2.0.0 and fixed in Django 2.1.3 (https://code.djangoproject.com/ticket/29827)
Two things - check out Factory Boy (for creating test data) and I would suggest checking out Pytest as well. With non-managed tables, the issue I think you'll run into is that (at least in my experience) django won't create them in the test environment and you end up running into issues because there is no migration file to create those tables (since they're unmanaged). Django runs the migration files when creating the test environment.
With Pytest you can run with a --nomigrations flag which builds your test database directly off the models (thus creating the tables you need for your unmanaged models).
If you combine Pytest and Factory Boy you should be able to come up with the ability to setup your test data so it works as expected, is repeatable and testable without issue.
I actually approach it like this (slightly hacky, but it works with our complex setup):
On my model:
class Meta(object):
db_table = 'my_custom_table'
managed = getattr(settings, 'UNDER_TEST', False)
I create the UNDER_TEST variable in settings.py like this:
# Create global variable that will tell if our application is under test
UNDER_TEST = (len(sys.argv) > 1 and sys.argv[1] == 'test')
That way - when the application is UNDER_TEST the model is marked as managed (and Pytest will create the appropriate DB table). Then FactoryBoy handles putting all my test data into that table (either in setUp of the test or elsewhere) so I can test against it.
That's my suggestion - others might have something a little more clear or cleaner.

How to test values which retrieve from db in jhipster

I am new to jhipster. I am trying to implement a test method to test values which are retrieved from mysql db. When I am trying to execute "gradlew test" command it will fail the relevant test case by saying "java.lang.AssertionError: No value at JSON path "$.[0].id". And I have added H2 Console db table values manually. My test method as follows.
#Test
#Transactional
public void getAllPlayersNS() throws Exception {
// Get all the playersNList
restPlayersNMockMvc.perform(get("/api/players-ns?sort=id,asce"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$.[0].id").value(1));
}
Where I went wrong?
As far as I know the integration tests in JHipster use H2 in memory so the changes you made using H2 console are probably not used by these tests and so our table is empty (this is what your failed assertion means) because they were stored in H2 on disk in target/h2db folder (if you chose this option at project generation).
So either, your test should create players using PlayerNSRepository or you should add a Liquibase migration that loads them from CSV (look at users.csv) and restrict it to H2 db and maybe using test Liquibase context.

EF and Code First Migrations with MySQL - dbo.tablename does not exist

I have set up entity framework to use MySQL and created a migration.
When I run update-database I get error "table dbname.dbo.tablename' does not exist. Running in -Verbose mode I see the statement that causes the error :
alter table `dbo.Comments` drop foreign key `FK_dbo.Comments_dbo.Comments_Comment_ID`
When I run the query direct in MySQL workbench is throws the same error.
The problem seems to be the dbo. prefix in the migration set. Anything in the form dbo.tablename won't run saying that table does not exist. E.g. select * from dbo.tablename fails but select * from tablename works. The database was generated by Entity Framework and the code first migrations were generated by EF too.
However the migrations generate everything with the dbo. prefix, which does not work.
Does anyone have a solution to this?
I was having this problem just today as well; found my answer here:
MySqlMigrationCodeGenerator
You have to set:
CodeGenerator = new MySqlMigrationCodeGenerator();
In your context's configuration class. This will get rid of the schema gibberish for MySQL. My Configuration class looks like this:
internal sealed class Configuration : DbMigrationsConfiguration<YourContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
SetSqlGenerator("MySql.Data.MySqlClient", new MySqlMigrationSqlGenerator());
SetHistoryContextFactory("MySql.Data.MySqlClient", (conn, schema) => new MySqlHistoryContext(conn, schema));
CodeGenerator = new MySqlMigrationCodeGenerator();
}
}
I have this same issue and I applied the solution posted by Sorio and It generated a lot of problems.
CodeGenerator = new MySqlMigrationCodeGenerator();
This code line can change all the sql that you generate, for example in my case in the sql code to apply to the database all the foreign key constraints disappear.
I am still without a solution because for me this is not acceptable and I recommend you to check the sql generate with the command before use this solution:
update-database -script

Hibernate: transfer the reverse engineered schema from SQL Server to MySQL

Newbie in Hibernate.
I've an existing schema in SQL Server and I used reverse-eng wizard in netbeans to generate POJOs from the schema. Now a decision has been made to switch to MySQL. Is there a way where I can run any hibernate utility to create tables and schema in MySQL from these POJOs?
Thank you
Bo
You can use the SchemaExport tool . It can be used via the command line , ant task or directly use the SchemaExport Class in the java code.
Here is the example to use the SchemaExport class ,
Configuration cfg = new Configuration().configure("your/hibernate/cfg/xml");
SchemaExport schemaExport= new SchemaExport(cfg);
/**First boolean means if print the generated DDL script to the console
Second boolean mean if execute the generated DDL script in the DB*/
schemaExport.create(true, true);
In the hibernate configuration xml , you have to specify your db connection info and your generated POJO from netbeans.