Base directory and schema_version - flyway

I just tested the commandline tool and I was able to migrate my database schema changes (DDL scripts) as expected. But I had to move all my scripts under the sql dir.
Is there a way to point flyway to the directory where my real scripts will reside (git or svn repository)? Looks like flyway.locations is only for relative paths.
The schema_version table name and column names are all created in lower case in my database (Oracle). The vast majority of people using Oracle are used to upper case object names and column names (default in Oracle). I found a property in the config file to set my own table name. Is there any to get flyway to use upper case for column names?
I checked the data inserted into version_schema after my test run. All look good except that the first character of the "script" column seem to be removed.
My prefix is "db_". Here is what I see in schema_version,
SQL> select "script" from schema_version;
script
b_1_0__test10.sql
b_1_1__test10.sql
b_1_0_1__test10.sql
atabase/db_2012_11_20__query.sql
<< Flyway Init >>

Lots of questions here (It's easier if you keep them separate). I'll try my best to answer them:
Not currently supported. See https://github.com/flyway/flyway/issues/108 . Symlinking can be used as a workaround.
No, there is no configuration property for the column names. The schema_version table is private to Flyway and not meant for outside consumption.
This sounds like a bug. Please file an issue containing your configuration (OS + version, DB + version, Flyway version, config file contents) and exact steps to reproduce.

Related

Database name as part of file name for file group

I am scripting out our database and because we have multiple stacks of drives assigned to each file group we have the files split into multiple files per file group also to split the IO / distribute storage among drives.
This currently is in SQL Server 2017 / SSDT in VS 2019
We always gave logical names to our database that started with the name of the database like how it is default in SSMS ex "MyDbName_FileGroup" then the file name similar ex: "MyDbName_FileGorup.ndf" but we never scripted this part before, we manually set that up.
I would like to get this scripted as part of the SSDT Deployment package so it can be used to set up new DB's easily also.
Everything is great so far made scripts for each file group that will create the files, but it of course will not let me use a SQLCMD variable as part of an object name.
So trying this
ALTER DATABASE [$(DatabaseName)]
ADD FILE
(
NAME=[$(DatabaseName)_FileGroupName],
FILENAME= '$(DefaultDataPath)$(DefaultFilePrefix)_FileGroupName.mdf'
) TO FILEGROUP [MESSAGING];
GO
does not work since I can't prepend the database name to the logical name like I want it to.
Yes this is purely cosmetic to match a pattern, but how would you go about doing something like this in SSDT?

Referenced table is not in dictionary

When I scaffold my database get the following error:
Referenced table `contentcategory` is not in dictionary.
Referenced table `contentcategory` is not in dictionary.
Referenced table `contenttype` is not in dictionary.
Referenced table `content` is not in dictionary.
I Use Mysql and Pomelo.EntityFrameworkCore.MySql
This is very likely to be a casing issue, where MySQL assumes the table name to be contentcategory for the reference, while it is actually something like ContentCategory.
We have a pull request for this open since April, that looks abandoned by the original contributor.
I will fix the PR and merge it, so that the workaround for this issue will be part of our nightly builds as of tomorrow.
The linked PR also contains the information of how this issue can arise:
Okay, that is in line with what I experienced as well. So manually (either by writing the name in the GUI or by using an ALTER TABLE statement directly) adding a reference with different casing (on a server with case insensitive file name handling) or disabling SQL Identifiers are Case Sensitive [in MySQL Workbench] can lead to this result.
Technically, this is a MySQL or Workbench bug, but we will implement a workaround for it anyway.

How to create Indexes with SSDT

Creating a SQL Function in SSDT works smoothly. When I modify the function's SQL, I can generate the DACPAC, then publish the DACPAC and the database is automatically updated. My function SQL looks like:
CREATE FUNCTION [dbo].[foo]
(
...
)
RETURNS int
AS
BEGIN
...
END
This is a file called foo.sql with build action to Build.
When I need to add a database index, I add an Index file to my project and put in:
CREATE NONCLUSTERED INDEX [idxFoo]
ON [dbo].[tblFoo] ([id])
INCLUDE ([fooVal])
If I try to build it I get several SQL71501 errors.
I was forced to add all Indexes in a common file set to PostDeploy.
I have found numerous references to including a DACPAC reference to the project-which I did. This works for most items, but not Indexes. I have no idea why.
I needed to add Table definitions to the project of the "missing" referenced objects in the Indexes. In order to get the script to create the tables, I used the VS Sql Server Object Explorer. Right click on table and select View Code (includes the table's existing Indexes and other elements). NOT Script As->(table create sql only) If you don't SQLPackage.exe will delete the Indexes not defined in your project.
Please ensure that all referenced objects are defined in the project.
The definition of all referenced objects must be present in your database project. This is because the database project is intended to represent the database schema as a valid stand-alone entity. Having this allows the tools to verify that your objects are correct -- i.e. that any references contained in them refer to objects that exist.

Can I rename Flyway migration scripts?

I have a project whose database is managed by Flyway in strict validation mode.
My migration files look like this:
V1.0__init.sql
V11.0__even_better.sql
V2.0__update.sql
V7.0__enhance.sql
The files are not displayed in the correct order (11 is between 1 and 2).
Therefore I would like to change them to look like:
V001.000__init.sql
V002.000__update.sql
V007.000__enhance.sql
V011.000__even_better.sql
The documentation says:
Leading zeroes are ignored in each part
This could mean that the above renamings are ok.
But looking at the schema_version table, the leading zeroes are kept, which seems like the above renamings would break the migration. So can I do the renaming, or will it blow up everything?
After trying it locally, it just worked.
The reason why I didn’t expect that is that the version numbers in the schema_version table include the leading zeroes, and the script column also mentions the original script in its full name.
But despite of that, validation succeeded after renaming the files.

Is there a way to query Oracle DB server name and use in conditional compilation?

I got bit trying to maintain code packages that run on two different Oracle 11g2 systems when a line of code to be changed slipped by me. We develop on one system with a specific data set and then test on another system with a different data set.
The differences aren't tremendous, but include needing to change a single field name in two different queries in two different packages to have the packages run. On one system, we use one field, on the other system... a different one. The databases have the same schema name, object names, and field names, but the hosting system server names are different.
The change is literally as simple as
INSERT INTO PERSON_HISTORY
( RECORD_NUMBER,
UNIQUE_ID,
SERVICE_INDEX,
[... 140 more fields... ]
)
SELECT LOD.ID RECORD_NUMBER ,
-- for Mgt System, use MD5 instead of FAKE_SSN
-- Uncomment below, and comment out Dev system statement
-- MD5 UNIQUE_ID ,
-- for DEV system, use below
'00000000000000000000' || LOD.FAKE_SSN UNIQUE_ID ,
null SERVICE_INDEX ,
[... 140 more fields... ]
FROM LEGACY_DATE LOD
WHERE (conditions follow)
;
I missed one of the field name changes in one of the queries, and our multi-day run is crap.
For stupid reasons I won't go into, I wind up maintaining all of the code, including having to translate and reprocess developer changes manually between versions, then transfer and update the required changes between systems.
I'm trying to reduce the repetitive input I have to provide to swap out code -- I want to automate this step so I don't overlook it again.
I wanted to implement conditional compilation, pulling the name of the database system from Oracle and having the single line swap automatically -- but Oracle conditional compilation requires a package static constant (boolean in this case). I can't use the sys_context function to populate the value. Or, it doesn't seem to let ME pull data from the sys_context and evaluate it conditionally and assign that to a constant. Oracle isn't having any. DB_DOMAIN, DB_NAME, or SERVER_HOST might work to differentiate the systems, but I can't find a way to USE the information.
An option is to create a global constant that I set manually when I move the code to the other system, but at this point, I have so many steps to do for a transfer that I'm worried that I'd even screw that up. I would like to make this independent of other packages or my own processes.
Is there a good way to do this?
-------- edit
I will try the procedure and try to figure out the view over the weekend. Ultimately, the project will be turned over to a customer who expects to "just run it", so they won't understand what any switches are meant to do, or why I have "special" code in a package. And, they won't need to... I don't even know if they'll look at the comments.
Thank you
As Mat says in the comments for this specific example you can solve with a view, however there are other ways for more complex situations.
If you're compiling from a filesystem or using any automatic system you can create a separate PL/SQL block/procedure, which you execute in the same session prior to compilation. I'd do something like this:
declare
l_db varchar2(30) := sys_context('userenv','instance_name');
begin
if l_db = 'MY_DB' then
execute immediate 'alter session set plsql_ccflags = ''my_db:true''';
end if;
end;
/
One important point; conditional compilation does not involve a "package static constant", but a session one. So, you need to ensure that your compilation flags are identical/unique across packages/sessions.

Resources