silverstripe / silverstripe-framework

Silverstripe Framework, the MVC framework that powers Silverstripe CMS
https://www.silverstripe.org
BSD 3-Clause "New" or "Revised" License
721 stars 821 forks source link

Ability to perform atomic database migrations #3868

Open patricknelson opened 9 years ago

patricknelson commented 9 years ago

Currently the SilverStripe framework lacks the ability to easily perform custom migrations at an atomic level. That is, SilverStripe has a very intuitive interface for defining database structure in a declarative format (e.g. "setup these columns with this format and these relations") but currently there is no method that I know of which facilitates a smooth and controlled atomic transition of database schema and the data contained therein. I'm not aware of any techniques by which I can change the way data is handled by DataObjects so I can deploy my code and database changes without leaving behind code to represent vestigial column names or data formats (for example).

Just a few more specific examples:

I noticed that there is some biolerplate code that introduces the concept in the framework here: http://api.silverstripe.org/3.1/class-MigrationTask.html

I'd like to suggest that we be able to do the following (things I'd be happy to try implement on my own, with permission):

Is there something already out there that does this (as a module) that I'm not finding or is this something we can implement? If so, what is the best approach? I'd be more than happy to contribute as much as I can. Any suggestions or recommendations would be appreciated!

camfindlay commented 9 years ago

@patricknelson this looks like something that should be added over on our feature request space http://silverstripe.uservoice.com, this could also be the basis of an RFC if you are interested in proposing something (so far we've just started using this process of RFC for bigger pieces of work see #3792 for an idea of what they contain).

patricknelson commented 9 years ago

Well, the RFC there seems pretty large and formal, so it's intimidating for me at first glance. On the flip side, I could submit a pretty informal suggestion and point it back here for formatting purposes. Do you think this might need to be in the form of an RFC to facilitate implementation? I suppose it depends on the overall internal impact, what SS wants and community feedback.

Anyway -- I went ahead and put something up here: http://silverstripe.uservoice.com/forums/251266-new-features/suggestions/7075780-ability-to-perform-atomic-database-migrations

I would definitely like to hear other people's thoughts (my own sort of "RFC") since I'd imagine this is another one of those "long time coming" features for those of us who have had experience with (read: "spoiled by") database migration tools in other systems. Honestly, for the type of functional and content heavy site I'm working on, it'll prove to be an extremely valuable tool.

dhensby commented 9 years ago

I think it'll be a bit much to expect @patricknelson to draw up a formal RFC (unless you're planning on implementing what you suggest).

My view (and one I've heard as well) is that migrations are a bit of overkill given the automatic schema builder present in SS. However, there is support for it given a recent post to the mailing list

When I'm faced with this problem I'll usually write my own migration script that is run as part of the deployment process. It's easy to create a task and then just run it after the deployment process.

patricknelson commented 9 years ago

The only problem (and the reason I don't think this is overkill) is due to one very important feature: The queuing of migrations and prevention of running migrations which have already executed. I'm just proposing a simple abstraction that would simplify and automate some of the redundant aspects of generating, de-duplicating and running migrations all in a single place.

The idea of using migrations is to handle that which dev/build does not (and cannot) because again it's working with declarative state. That is, the DataObject model just says what things should look like right now and dev/build will do what it takes to augment the current schema to make that happen. That's fine, but what happens when you have a site that's live in production which needs to have a new release deployed and you've had to restructure your code for clarity, bug fixes and etc but dev/build isn't smart enough to move/copy data from old columns into new ones? That's where migrations come in and the need to ensure there's a central mechanism for tracking what has and has not been run.

I like what Gregory has done and outlined in his message. As you can tell this is a common problem which, due to the lack of existing features, is possibly being re-implemented independently by developers who need it. Ideally we'd have a very good baseline (generic and extensible) abstraction which can handle the most common use cases and give power to the developer to do everything else they need.

As you can tell from the message, some common functionality (which is typical of migration systems) such as:

Check out Laravel to see how they do it and get an idea of the context of what I'm referring to (just in case). That is where I've gotten the bulk of my migration experience. http://laravel.com/docs/4.2/migrations

patricknelson commented 9 years ago

Also, I agree that migrations will be overkill for a large portion of the people who may adopt SS. However, implementation for me would be reasonably trivial considering the payoff would be quite high if I'm not the only person who ends up benefiting. Especially if you're in a situation like I am where you may need that extra bit of control on how the data is structured over time for complex content-heavy websites where requirements are shifting constantly (unfortunately real-world issues necessitate these continuous changes, sometimes).

Even if the system isn't changing frequently, it's always fantastic to know you've got a way to automate your deployment process consistently across the board.

patricknelson commented 9 years ago

Funny -- I'm also just happening to notice this recently revived discussion here too: https://groups.google.com/forum/#!topic/silverstripe-dev/niQhqfK-h44

And: https://groups.google.com/forum/#!topic/silverstripe-dev/ebKhtcmgwRc

I can tell I'm not far off by indicating that this has probably been re-invented over and over again by other developers with the same need. People should definitely be pointed to the same place so we can tackle this centrally and coordinate our discussion and efforts. It seems people may not be dropping them into http://silverstripe.uservoice.com/ (at least not with the terms "migrate" or "migration").

patricknelson commented 9 years ago

I posted a message in the discussion list but wanted to link here as well. I setup a module for this in case anyone finds it useful!

https://github.com/patricknelson/silverstripe-migrations/

chillu commented 7 years ago

@dhensby suggests moving to dbal, which would allow for using https://github.com/doctrine/migrations/

bummzack commented 6 years ago

I've seen there's a MigrationTask in SS4, but somehow there's no way to specify the Direction param, or am I missing something?

patricknelson commented 6 years ago

@bummzack That doesn't even really do anything, not sure why it's been kept since its mere existence is confusing (https://github.com/silverstripe/silverstripe-framework/blob/master/src/Dev/MigrationTask.php).

If you want atomic database migrations, I've got a module I built and have had in use for several years now (circa early 2015 or so) which has served me very well: https://github.com/patricknelson/silverstripe-migrations

Please give it a shot on SS4 and if you have any issues (likely as I've not tested it in SS4) please feel free to submit a PR!

lekoala commented 6 years ago

just a quick note relative to the MigrationTask class : if someone can make it abstract so that it stops showing up in dev/tasks for no reasons, that would be great :-)