Generate new liquibase changelogs when updating one entity and don't rewrite previous changelogs linked to this entity.
One first possible implementation would be to add these options to jhipster entity Entity
command tool for the question "Do you want to update the entity ?" :
Yes, add more fields and relationships and write new changelogs for database updates
Yes, remove fields and relationships and write new changelogs for database updates
And then, new changelogs files for liquibase will be created : updated_entity_Entity.xml
and updated_entity_constraints_Entity.xml
We can also extend this feature to import_jdl
tool, when a new JDL schema is imported, we could make a diff between current fields/relationships and new fields/relationships from JDL schema for each entity and generate corresponding liquibase changelogs files.
When you have an existing jHipster project in production and you want to update one current entity, you have to manually create a new liquibase file for updating your database.
The idea with this feature is to generate a new liquibase file for new or removed fields/relationships when you update one entity and save time.
I didn't find a similar feature request. I'm available to work on this feature.
Previous work that was never finished: #6016
how do you manage to remember this, @gmarziou ?!
nice link to this ticket !
:) Because I remember answering several times about this highly requested feature on SO.
Hi, I tried a small implementation of new changelogs generation when updating entity with jhipster entity EntityName
command line tool. I didn't write test for the moment and I don't know if my implementation will work well with all cases but I tested successfully for the moment :
After selection of 'Add' or 'Remove' in options for update type, the user is asked if he wants to generate a new changelog for updating database.
And after, new changelogs files for liquibase are created : updated_entity_Entity.xml
and updated_entity_constraints_Entity.xml
Here a demo video :
https://drive.google.com/file/d/1AfQGmgbZJ5sE9oRNvYnpdv0uB7gXVQq2/view?usp=sharing
Tell me if I can open a pull request for this first part in order to have feedbacks on it, thanks.
Thanks @ntorionbearstudio for this excellent work, the idea of the video is excellent too.
Tell me if I can open a pull request for this first part in order to have feedbacks on it, thanks.
@ntorionbearstudio you definitively should open the pull request, preferably as Draft Pull Request.
- Does it work also when updating the entity through import-jdl?
@gmarziou Not for the moment, I only implemented this in jhipster entity CLI part for now
@ntorionbearstudio : I saw your video and it's impressive ! good job :)
Now, I'd like to know what you have in mind for JDL ? Is it possible or not ? Maybe use a flag ?
I changed the label as it's not a simple enhancement but a very good feature.
I added a bounty too, as if we manage to achieve this, it will help a lot of users
@MathieuAA I am wondering on how to add this feature to jdl?
Looks like https://github.com/jhipster/generator-jhipster/pull/6016 was doing diff between the imported code and the new code.
I like this approach
This implies knowing the format of this diff, maybe something like:
Yes I think that a diff between previous and new imported JDL schema could work (I don't well import JDL part so maybe I'm wrong).
I was thinking to add a new option to import-jdl
command line like this :
jhipster import-jdl jhipster-jdl.jh --new-changelogs
With this option import-jdl know that he has to do a diff between previous and new JDL schema, and generate some lists to send information to jhipster generator :
inside an updated entity :
Work on #6016 will help us to do diff between JDL schemas.
I will discover in the next days how import JDL works in the source code to have a better vision on it
And how would the generator know there's a diff to be read afterwards?
Why passing a --new-changelogs option?
Let's embrace changelog immutability and always create a new changelog for each change.
This is a core concept of Liquibase and the reason why changelogs are checksumed.
I just pushed an updated version of this feature:
app -> entity -> entity-server
doesn't work for this feature.app -> liquibase (each changelog) -> entity -> (entity-server & entity-liquibase)
, when no changelog is found it fallback to app -> entity -> entity-server
.jhipster liquibase
show prompts to add entities and change entities.jhipster liquibase --merge
allows to merge multiples changelogs from one entity.jhispter liquibase --drop
allows to drop a changelog.jhispter liquibase --custom-changelog foo
creates a file on master.xml for custom changelogs.jhispter liquibase --import-jdl foo.jdl
jhispter import-jdl
:Others todo:
@mshima why mutating changelogs (change, merge, drop)? I'm really concerned about violating Liquibase immutability principle.
@gmarziou
liquibase --rollback
will do the trick here.@gmarziou creating liquibase tags should be useful here.
jhipster liquibase --create-tag v1.0.0
Drop and merge should ignore every change before any tag.
@mshima
The developer should take care about this.
OK but tools should promote safest practices, so default behavior should be to generate immutable changelogs. Then for developers who know what they're doing, they can use the options you propose.
Let's compare it with rewriting history in git: it's very useful but it can be dangerous if you do it on a branch that has been exported and used by others. This is why default behavior for git push
is to reject rewritten history, then it's up to developer to use --force
option. It's the same for Liquibase once a changelog has been pushed to production.
JDL: jhispter liquibase --import-jdl foo.jdl
Why not integrate into jhispter import-jdl:
- jhipster import-jdl writes directly to the file, I changed jhipster-core to don't write, just return.
How so? If it's just a matter of adding a new flag, it's pretty easy.
JDL: jhispter liquibase --import-jdl foo.jdl
Why not integrate into jhispter import-jdl:
- jhipster import-jdl writes directly to the file, I changed jhipster-core to don't write, just return.
How so? If it's just a matter of adding a new flag, it's pretty easy.
The jhipster-core part is easy.
The cli part can be complex, not sure, probably it should be rewritten as a generator.
And what I mean is that this is not the focus right now. The liquibase generator should be mature first.
Hello, I discovered JDL import part in source code during the last days.
So, I tried to link it with what I have already done on jhipster entity
command line tool and I managed to make it work with JDL importation. Here is the demo link with JDL schema update :
https://drive.google.com/file/d/1uV-mJdPHdpKc8GYVJaePZT2unVYHpE-4/view?usp=sharing
How it works :
Entity-previous.json
)Entity.json
) and if exists, previous entity description (Entity-previous.json
)newFields
newRelationships
removedFields
removedRelationships
These lists are used by previous implementation on jhipster entity
command line to generate corresponding new changelogs for Liquibase.
This solution is incremental, there is no way for the user to merge or manage his changelogs like @mshima propose. Jhipster generator will only generate required new changelogs corresponding to user updates on entities to make it work in production.
To my mind @mshima solution is far more interesting to allow user to do specific and more avanced operations on liquibase changelogs, my solution could be used for simple cases when user only wants to update his entites without have to manage liquibase changelogs by himself
this looks awesome!
I have a question, how does it behaves when editing the same entity multiple times?
What about relying on the liquibase maven (or gradle) plugin at the end of an existing change?
Seems simpler to answer the use case and I would prefer to rely on a tool that has been made for that than a bake our own solution which will hardly achieve the same.
I also like the idea to promote the same approach (generating diff) for jhipster jsons: doing so, the framework could become more incremental than it is in its generation strategies. But it should be expressed in a dedicated issue and fill another need :-).
this looks awesome!
I have a question, how does it behaves when editing the same entity multiple times?
Hello @amatosg, there is no problem for updating multiple times the same entity, because each time Entity.json
and Entity-previous.json
will be updated and a new changelog will be created
Regarding the new sub generator can we use a more generic name, like data-migration
or kind of.
2 main reasons:
At the end it's just a name but I would prefer to stick with concepts/pattern/layer names in the sub gen naming and let the code use whatever implementation (like client vs angular, server vs spring, etc).
WDYT
@ntorionbearstudio how is this going on? did you have time to finish? maybe a PR would be nice :)
@amatosg you can try https://github.com/jhipster/generator-jhipster/pull/11423
@ntorionbearstudio how is this going on? did you have time to finish? maybe a PR would be nice :)
Hello @amatosg I opened this PR : https://github.com/jhipster/generator-jhipster/pull/11419 I'll try end it soon (with tests)
@mshima thanks but I think @ntorionbearstudio is a cleaner approach. The current behavior doesn't take any parameters (like versioned-database
or --custom-changelog
) and I don't see why new options or parameters are needed, it over-complicates the feature IMHO.
The current logic is to update the files and this new approach is to create a new file and add the reference to the master file (which is something I have to do manually very often).
Of course this is just a personal preference on how the feature should behave.
@amatosg I don鈥檛 get why it鈥檚 not clean. jhipster versioned-database --init liquibase
is because I don鈥檛 want to make it default now. Once is called no more command is needed, neither for import-jdl nor for prompts.
--custom-changelog is to register your manually added file, so you don鈥檛 need to manually change master file everytime.
@mshima well, I didn't say it's not clean, I said it's _cleaner_. When you say you don't want to make it default _now_, I understand and it will become default in a near future? I think this could lead to confusion. Again, this is just my opinion.
I have a couple of questions that I think @ntorionbearstudio addresses in his PR.
The current logic is to created a versioned db. Why would I need to call jhipster versioned-database --init liquibase
? Wouldn't it make more sense to call something like unversioned-database
?
Do I call jhipster versioned-database --init liquibase
before o after the project has been generated? (Either way I have to make 2 calls to jhipster, right)
I think adding --custom-changelog
is overcomplicate a simple functionality as adding one line to the master.xml
is fairly simple.
@ntorionbearstudio I just released the blueprint generator-jhipster-liquibase. Can you try it?
If you still planning working on your PR, I should create a new issue to track incorporating generator-jhipster-liquibase into core generator-jhipster.
Just run jhipster --blueprints liquibase
and it will generate a changelog for every field added/removed and relationship added/removed.
Related to this comment: https://github.com/jhipster/generator-jhipster/issues/11398#issuecomment-597622692, I also need changements on jhipster-core to make the new changelogs generation work on JDL importation
PR -> https://github.com/jhipster/jhipster-core/pull/469/files
hi @ntorionbearstudio
It would be awesome to have this feature in v7.
Also, do we plan to let the choice to the user to choose between adding liquibase diff or rewrite the old changelogs? (it could be useful).
@avdev4j since this PR is kind of stateless, then it's not possible to regenerate a old changelog if one partial changelog exists.
Ex:
1) Generate Foo inside initial changelog: eg. 20200601.
2) Add newField
field to Foo inside second changelog: eg. 20200603.
20200601 -> 20200603 diff cannot be reconstructed if the history is not saved.
@avdev4j what can you tell me about https://github.com/jhipster/generator-jhipster/pull/11833?
This is required for implementing incremental liquibase changelog https://github.com/mshima/generator-jhipster-liquibase.
A new implementation of https://github.com/jhipster/generator-jhipster/pull/11833 is inside blueprint https://github.com/mshima/generator-jhipster-customizer/tree/master/lib.
If you agree with lazy calculating entity/field/relationship data I can create PRs.
Hello, sorry for the delay on this feature. Currently I have 2 PRs for this feature :
https://github.com/jhipster/generator-jhipster/pull/11419 : I need help for tests, I don't know how it works inside the project, I wrote a comment on it inside the PR
https://github.com/jhipster/jhipster-core/pull/469 : I have feedbacks to treat and @mshima idea to apply, on this too I need maybe some help
@ntorionbearstudio for the JCore part, do ping me for help :)
Hello, sorry for the delay on this feature. Currently I have 2 PRs for this feature :
- #11419 : I need help for tests, I don't know how it works inside the project, I wrote a comment on it inside the PR
- jhipster/jhipster-core#469 : I have feedbacks to treat and @mshima idea to apply, on this too I need maybe some help
Hello I'm working on it this week to complete the feature
My work on it was done with some tests on new generated changelogs : https://github.com/jhipster/generator-jhipster/pull/11419 but like I have written on the PR, with @mshima 's work on https://github.com/jhipster/generator-jhipster/issues/12178 this issue can be considered as closed I think
@pascalgrimaud Can you confirm this can be closed?
@DanielFran : I don't know, I wanted to test this feature but didn't have the time yet, because of preparing JHipster Code... Only @mshima knows :)
@pascalgrimaud @DanielFran I think so.
Ok. So let's close it
Most helpful comment
Why passing a --new-changelogs option?
Let's embrace changelog immutability and always create a new changelog for each change.
This is a core concept of Liquibase and the reason why changelogs are checksumed.