rdagumampan / yuniql

Free and open source schema versioning and database migration made natively with .NET/6. NEW THIS MAY 2022! v1.3.15 released!
https://yuniql.io
Apache License 2.0
417 stars 63 forks source link

Support for multiple environments #255

Open coredat-abru opened 2 years ago

coredat-abru commented 2 years ago

I have a setup where I'd like to apply migrations for multiple environments at the same time. I want to use this in order to be able to apply specific migrations for specific features only. As an example, say I'm developing feature "Foo" and have the environments "dev", "staging" and "prod", I'd setup my version folder the following way:

vx.xx
|-  _dev
|-  _dev_Foo
|- _Foo
|- _prod_Foo

In this example _dev would run if dev was set dev_Foo would run if both dev and Foo are set Foo runs if Foo is set prod_Foo would run if both prod and Foo are set

From what I understand, the bulk of this change would be implemened https://github.com/rdagumampan/yuniql/blob/01465775b1d19604222d4a511dd9a13e0ae40f97/yuniql-core/DirectoryService.cs#L51 Is this a feature you would be willing to support? If yes, then I'd be happy to provide a PR

rdagumampan commented 2 years ago

@coredat-abru, thanks for reaching out and your interest with yuniql. I am super amazed of these unique use cases! :). I'm scratching my head right now...

Maybe we can achieve this flexibility using git branches. What do you think? Me thinks, feature branching is the strength of tools like git so you can create Foo branch from dev branch and have scripts under _draft directory. Then the feature is complete, you can PR the feature branch back into dev or master and you can move the scripts to vxx.xx or any directory it best fit. Or you can move the scripts from _draft into vxx.xx in the feature branch and then PR into dev or master.

In your idea, you can treat any directory with _ prefix as an environment or branch. The concept of environment is merely a toggle flag of which script to execute in the migration session. So you can do any of these:

yuniql run --environment dev
yuniql run --environment dev_Foo
yuniql run --environment Foo
yuniql run --environment prod_Foo

P.S. Please star our repo ICYMI. It goes a long way in getting better stats and helping more people discover this tool :) Thanks!

coredat-abru commented 2 years ago

In my particular case that would wouldn't offer the flexibility I'd need. There are some I'd like to always run in dev, including dev_Foo, dev_Bar - or just in dev. Currently I'd have to duplicate my migration scripts everywhere.

To give you some background, I'm using the same code base in multiple environments where certain features require certain adjustments to the database.

I kind of needed this to work today because I messed up and went and did a quick and dirty implementation of this here: https://github.com/Coredat/yuniql/commit/48bfd8f3c487ee7ed2d4c3c9bca2c9c01bf43cdb And run it like so yuniql run --environment "dev,Foo"

With my immediate need out of the way, I'm happy to discuss alternative approaches.

ps: done :)

coredat-abru commented 2 years ago

Just to clarify, I didn't create a PR because I'm not sure if that's what you want. But I'm happy to do so.

rdagumampan commented 2 years ago

@coredat-abru, sorry for delays. Im still trying to understand better this use case but I am glad you found a quick solution that works for you. Can you describe this more specific, maybe attach some visuals how this idea work. Our initial idea on environment is that every environment points to a unique connection string or different database like (mydb_dev).

Maybe you can describe how your server infrastructure, databases or schema. Appreciate if you can do this. I'm very curious. Have a nice weekend.

coredat-abru commented 2 years ago

No worries :)

The way our application is written is that we have one code-base for all our customers. For this reason a lot of our features and available functionality is being configured via the database. We deploy separate database instances for each customer. This means that I need to be able to change the database on a per customer basis (mostly INSERTs and UPDATEs).

And then there are differences between Dev, Testing, Staging and Prod.

Example, there are 3 customers: Foo, Bar and FooBar: image The numbers 1,2,3,4,.. represent features that are activated if the number is positive or deactivated if the number is negative. Column "All" would apply to all "customers". To put this into words:

I hope the explanation is better than the last one.

kamalsivalingam commented 2 years ago

Thanks a ton @coredat-abru, You saved my day. Had to pass the environment name in quotes and worked.