Manage SQL Schemas with Flyway: Key Concepts and Examples
- posthersnunmoochar
- Aug 17, 2023
- 6 min read
"With Flyway you can combine the full power of SQL with solid versioning. This makes setting up and maintaining database schemas a breeze. We use it across all environments including production, making it a perfect fit for our continuous delivery and zero downtime pipeline. I highly recommend it."
Manage SQL Schemas with Flyway
If you have multiple developers developing code, you can use an S3 bucket to keep track of all SQL changes and sync the bucket with the local EC2 instance $flyway_home/sql directory and push those changes to the respective database.
run with flyway.defaultSchema=julia is equivalent to CREATE TABLE julia.MyTable (...). If we want to interact with other schemas, we need to use fully-qualified object names. This schema is also where we will put our schema history table.
Sets the default schema managed by Flyway. This schema name is case-sensitive. If not specified, but schemas is, Flyway uses the first schema in that list. If that is also not specified, Flyway uses the default schema for the database connection.Consequences: - This schema will be the one containing the schema history table. - This schema will be the default for the database connection (provided the database supports this concept).
Comma-separated case-sensitive list of schemas managed by Flyway. The first schema in the list will be automatically set as the default one during the migration. It will also be the one containing the schema history table.
Whatever development methodology you use, it is useful to have, and independently maintain, a separate schema within a database for utilities. These utilities are database objects that monitor the functioning and operation of the database, but aren't part of the database. This article demonstrates how to manage these utilities from Flyway so that we can maintain and migrate them separately from the database objects.
We have created a util schema in several databases, and managed migrations to the schema, so we can keep them updated. Flyway will manage just the schemas in the list you provide, though it will create, alter or delete objects in other schemas within the same database.
So far, so good. We are getting each of our build scripts being executed within a transaction so that we are not left with the debris of a half-complete build if it fails, and the current version is being recorded in the description column of the flyway_schema_history table.
The advantage of putting one of your config files in the user home directory, or a subdirectory of it, is that credentials, particularly passwords, are protected there from being seen by other users. Configuration that is relevant to all users can be placed in the installation directory, and all the details for the project can be placed within the project. You can then run the current project by making that the current directory. After looking in the install directory for a flyway.conf configuration file, it then checks the user area, and then finally the current directory. It will find your config file that tells it where to find the database, credentials if necessary, and the script files.
The flyway_schema_history table is exclusively for use by Flyway. It is a bad idea to edit or update it directly. It is best to read the information contained in the table by using Flyway Info. This information can be obtained as a JSON file by setting the command-line parameter accordingly with - outputType=json. If you need to alter the contents of the table, it is almost always possible to do so via a Flyway action.
On most database systems, you can place the flyway_schema_history table in a different schema. The problem with putting it in a different schema is in the differing ways that databases support schemas. It is fine in SQL Server or PostgreSQL, for example, but not in MySQL or SQLite.
The key for this process to work is to enable the baselineOnMigrate flyway option, in short, it will create the flyway control table (flyway_schema_history), setting the first row as the existing migration script you created in the previous step, without it, the flyway process fails because it detects that the database has an existing schema without the flyway control table.
Liquibase uses a unique identification scheme: an ID and author, along with the name and path of the file all in a changelog. This makes it easy to manage the order in which database changes are made. This way of managing the changes makes developer conflicts and collisions less likely since there are multiple factors that drive the uniqueness of a given change. The only possible problems you can encounter are with XML merge conflicts, which can typically be resolved with version control systems like Git.
We wanted to keep database migration script with each Microservice rather than keeping a common module to manage database Migrations. We might later migrate to common module for database migration but we want to start by keeping schema for each Microservice separate.
The default schema managed by Flyway. This schema will be the one containing the schema history table.If not specified in schemas, Flyway will automatically attempt to create and clean this schema first.
First off, we need a way to manage the database schema - creating tables, etc.I've used Flyway for the past few years as a simple and flexible wayto manage database schemas alongside source code,and I wanted to incorporate it into my Ktor projects as well.
A given dacpac, with say version 5, can be applied to a database which is on Dacpac version 1,2,3,4 or 6,7,8 etc. If its applied to 1-4, the database will be upgraded. If applied to 6,7 etc., the DB will be downgraded/rolled back. There will be warnings, if there will be data loss, which can be suppressed. So, we get a great rollback feature, which is not available with other tools like flyway etc. With flyway, one has to provide a new set of scripts for rolling back.
As always in our industry, there is no silver bullet in database schema change management. Plenty of tools can be used to manage database migrations, but each will have its own philosophy and drawbacks. For our project, it seems unreasonable to go for EntityFramework or FluentMigrator, since they store migrations as code, not plain SQL files like those we already have. This leaves us with RoundhousE or DbUp, and as of now I tend to favor DbUp because of its simplicity, even knowing certain limitations. Extra cognitive load can render all other benefits useless, so whenever possible I try to use the simplest possible tool.
Note: Originally the idea was to tell Flyway to read SQL files from the volume without copying or moving them to the container home directory. However, we faced an issue with this configuration:(See flyway issue 1807 on github). Indeed the Flyway engine will recursively read the volume, including the hidden subfolder. There is a Request for Enhancement to customize this behavior and prevent Flyway from reading meta data files in the volume mount folder.
Increasingly we are seeing people use multiple schemas as part of a single database environment. We've worked with projects using a handful of schemas like this, but haven't yet cranked this up to tens or hundreds of schemas. This is a situation that we anticipate having to deal with in the next few years.
Each of these folders can be tracked separately by the database migration tools such as Flyway, dbdeploy, MyBatis or similar tools, with a separate table to store the migration numbers. The property flyway.table in Flyway is used to change the name of the table where the migration metadata is stored
Similarly, there are scripts to delete schemas - either because they are no longer needed, or merely because the developer wishes to clean up and start again with a fresh schema. Database environments should be phoenixes - regularly burnt down and rebuilt at will. That way there's less danger of environments accumulating characteristics that aren't reproducible, or audited.
This is exactly the practice of Continuous Integration, which is commonly used with application source code management. The steps above are just about treating the database code as another piece of source code. As such the database code - DDL, DML, Data, views, triggers, stored procedures - is kept under configuration management in the same way as the source code. Whenever we have a successful build, by packaging the database artifacts along with the application artifacts, we have a complete and synchronized version history of both application and database.
Using the techniques we describe here may sound like it is a lot of work, but in fact it doesn't require a huge amount of people. On many projects we have had thirty-odd developers and a team size (including, QA, analysts and management) of close to a hundred. On any given day we would have a hundred or so copies of various schemas out on people's workstations. Yet all this activity needed only one full time DBA with a couple of developers understanding the workings of the process and workflow doing some part-time assistance and cover.
47 Degrees can work with you to help manage the risks of technology evolution, develop a team of top-tier engaged developers, improve productivity, lower maintenance cost, increase hardware utilization, and improve product quality; all while using the best technologies. 2ff7e9595c
Comments