Sequelize: Sequelize.sync() should support ALTER statements instead of full DROP+CREATE statements

Created on 11 Apr 2013  Â·  107Comments  Â·  Source: sequelize/sequelize

It would be nice if we could call sync() and have it compare the model schema to the database schema and make only the changes necessary using ALTER statements. The major benefit is preservation of data. If implemented correctly, this could probably eliminate most of the need for migration files.

feature

Most helpful comment

_Note_: Please use reactions instead of filling the thread with +1 comments

All 107 comments

That would be really awesome, yes. I just had a look on jugglingdb - they do it with a method. As it is really dangerous to delete data, when changing a model I would prefer the solution jugglindb had ( http://jugglingdb.co/schema.3.html ).

schema.isActual(function(err, actual) {
    if (!actual) {
        schema.autoupdate();
    }
});

I really like this feature. The reason I don't use sequelize yet is because this is not available yet.
The schema's we use have to be updated very often en quickly because new data has to be stored.

Hi! Did you already find a way to do a DB sync in sequelize without wiping out all records? Thanks!

I made use of sequelize's migrate tool to keep the DB in sync with the models, it's a bit more effort but it seems to work fairly well

Will look into that. Thanks!

Anyone working on a PR?

Not yet, it's a major feature. It's something i really want to do but its not my highest priority.

+1

This would make my life so much easier! +1

Just an update for you all:

We have been considering this - And we need to do a few things:
A mechanism for identifying a difference between the current model schema and the target table schema. Also needs to identify missing junction tables ideally.
This difference needs to be represented by some kind of data structure.
This data structure could then be transformed to either a manual migration (allowing inspection) or to sql and run by sync.

As for a timeline, we probably want to look at improving the migration ecosystem first, since that's a very viable solution to this issue aswell.

@mickhansen If you need a beta tester please give me a holler!

I think that despite comparing model schema with db schema, it should still generate migrations instead of updating database on the fly. First of all it would allow to look through migrations history and migrations details.

@alekbarszczewski like i wrote, if you design it properly it generating migrations or updating the database on the fly would be same basically. All the work lies in identifying changes, if you can then represent those changes in a data format you could easily generate either SQL or migrations from them.

@mickhansen agreed :)

+1, looking forward to it :)

@gustavpursche I do like the jugglingdb way of being able to check if a sync is needed

+1

+1 That is the only reason why I don't use sequelize. Even doctrine 1.4 was generating migrations from diff.

+1

I agree, this would be wonderful.

+1 *N .haha.

Started diving into sequalize as I realized that there are no updates on schema with alter.
Right now I will use Sequalize after all, but writing simple migrations by hand is somehow waste of time for me, because I'm also using Symfony2 with Doctrine at many side projects.

Looking forward to see auto migrations in Sequalize

+1

huge +1

I was hoping there was a way of detecting an out-of-sync model, that should be top priority, automatically creating the migrations seems so much harder than just listing columns and finding a mismatch.

@Madd0g well there's also a whole group of people that think something like this would be really irresponsible - what if there's a bug that suddenly whipes your table for some reason? (bugs happen in software, often).

It's not our highest priority, but something we do want to get to (but we are really only two developers in our spare time :))

@mickhansen - I meant that being able to see that a model is out-of-sync should be top priority among other related things like auto-migrate and other _really_ scary and complex things like detecting/fixing out-of-sync properties in relationships.

Just detecting the change within a single model and not doing anything until the dev chooses to do force: true, is not really dangerous. I would really welcome that feature.

@Madd0g Yeah ideally i would like to be able to run a base diff that can present the differences in some kind of format that we can then either transform to migrations, raw queries or execute immediately.

+1

+1

I was initially really impressed with sequelize and coming from the .net world where I could do things much faster using framework like Entity Framework but the issue with sequelize is It really does not provide a way to sync the models and database other than using migration scripts and I am sure no programmer in the world would really like to update database on 2 places, models and then writing the migrations for them. I think if the sync {force: false} option is provided which could sync alter tables also then there is no need for migration scripts and those will become obsolete.

@zeeshanjan82 I would personally never use sync({alter: true}), and i'm a contributor. Bugs happen and i wouldn't want my production DB to disappear because of MAGIC.

Now 2 years after my comment I agree to @mickhansen. I still think it would be nice, to allow an altering process, but since sequelize-auto already exists, it's not that hard, to create visual diffs or even replace/ enhance your model files ...

@gustavpursche It would still be a nice feature since the underlying functionality could be used to generate migrations you could manually inspect before running.

@mickhansen Agree. But 2 years ago I gave my "+1" to auto-altering the table, without manual checks, why I wouldn't anymore. Maybe a long winter-night will bring a "sequelize-model-diff" to life :)

+1 to it, would be awesome.

Django even integrated south into the core.

link provided above: http://south.readthedocs.org/en/latest/commands.html#schemamigration

already integrated on django:
https://docs.djangoproject.com/en/1.8/topics/migrations/
https://docs.djangoproject.com/en/1.8/ref/django-admin/#django-admin-makemigrations

+1

+1

+1

+1

+1

+1

+1

I've just released an open source module that compares two postgresql databases and generates SQL statements to modify the schema so the first db matches the second one.

https://github.com/gimenete/dbdiff

@gimenete You are a champion among men.

@GeoffreyPlitt Feel free to open an issue if you find something that could be improved or any suggestion :)

+1

+1

+1

+1

+1

+1
We could use https://github.com/gimenete/dbdiff as starting point.

@n321203 However dbdiff is only part of the way - since it only supports postgres, and as far as I can see needs to connect to two existing databases

@janmeier I'm the author of dbdiff. I can make dbdiff support other databases in the near future. Which database are you using?

I don't think sequelize should use dbdiff internally to start supporting alter sql statements in .sync() but one thing we could do is a new module that using dbdiff and sequelize calls sync() in an empty database and compares this database with the regular one.

@gimenete MySQL, SQLite, Postgres, MSSQL
dbdiff looks great but i'm not sure it's a fit here, a better approach will likely still be to have describeTable work well enough that it can be compared to the attributes a model has.

@mickhansen @janmeier @n321203 I've just released a module that uses dbdiff behind the scenes. It adds a new method to Sequelize: syncDiff(). Check it out:
https://github.com/gimenete/sequelize-sync-diff

It only supports Postgres though. I could add MySQL in the near future.

+1

+1

_Note_: Please use reactions instead of filling the thread with +1 comments

+1

I've released a new version of dbdiff https://github.com/gimenete/dbdiff

This is a big refactoring and the first step for supporting multiple databases. Also now it can be used as a library (not only a cli) to compare two databases, two schemas, or generate a JSON-serializable object with the schema representation of an existing database. This could be integrated into sequelize this way: sequelize could create a "desired" schema representation and dbdiff could compare it with the current database schema. @mickhansen

I've also added "safety" levels of the SQL output. Check the docs for further info.

@gimenete WOW! Actually developers of sequelize should consider using your library

will this be considered in 4.0 release?

@xiaofan2406 It's not breaking so it's not tied to any specific release.

+1

+1

+1

make 2 parameters --dump-sql and --force like in Doctrine2 schema tool. --dump-sql to write migration SQL into console only. This is a safe way to migration on production database. And another key --force for applying commands to target database

apgdiff http://apgdiff.com
maybe help to migrate from different versions of PostgreSQL schema generated by sequelize.
just use
pg_dump --schema-only "address-to-your-old-postgresDB" > ~/Desktop/schema0
pg_dump --schema-only "address-to-your-new-postgresDB" > ~/Desktop/schema1

and use apgdiff to generate alter commands.

Any update on this after two years?

I think the easiest way to implement this feature is to use sql diff tool to generated alter SQL

+1

Please don't +1 issues. It clutters the thread without adding value to the discussion and spams maintainers with notifications. Use GitHub reactions to upvote features.
image

Still no PR about this ?

This issue opened 4 years ago, And how's the work?

@TangMonk Appearently no-one has needed this enough that they actually took the time to sit down and write the code (Which would require a significant amount of time).

Remember that almost everyone here works on sequelize on their own time :)

@janmeier sorry, I understand, thanks everyone's work, I wish I could help.

Can't wait for this to be out. Will come very handy and wouldnt have to drop table to see new changes!

+1

We've been using Sequelize in Production. Not having this option is leaving us stumped trying to find the best way to make modifications to the database in a production environment.

I've submitted a patch for this. #7230

Just waiting for a merge, but you can use my branch for now if you really need this feature - jmeyer2k/sequelize

dear god

good job

How Work ? link doc? video?

sequelize.sync({ alter: true })

Do I need to update sequelize via npm or need a specific branch?

It seems that the latest version v3.30.4 does not include this change. Wait for release.

This feature has landed in master, so it will be available in v4

@janmeier Friend, this functionality is important when you could leave this version thank the collaboration.Friend, this functionality is important when you could leave this version thank the collaboration.

Woah! It made it!!!!!!!

Yeah, but latest pre-release is 4.0.0-2 from 2016-09-12T07:13:18.104Z.

Is there a plan to release 4.0.0-3 which would include this feature?

Any update about this feature?
For me it's clearly a game changer regarding the choice of an ORM. Have been using knex for a while, but schema updates and migrations are such a pain.

It's in master. It will be released in 4.0.0 otherwise you can use the
github version.

On Mon, May 1, 2017 at 5:26 AM Vincent notifications@github.com wrote:

Any update about this feature?
For me it's clearly a game changer regarding the choice of an ORM. Have
been using knex for a while, but schema updates and migrations are such a
pain.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/sequelize/sequelize/issues/537#issuecomment-298326392,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABMIk93yFxsvUica5rOW1xke1077uYd7ks5r1c-PgaJpZM4AkYlY
.

@meyer9 Did a couple of changes to your implementation that fixes column mappings and added a drop column option (so that columns are not dropped by default). Also fixed query generator for unique and foreign keys alteration for postgresql (don't use enum on my side, perhaps that might still be problematic).
Since you have the test scenarios/environment, perhaps you can validate the changes to be working correctly also on your side.
repo: https://github.com/lekkerapps/sequelize

Thanks

Looks great! There are a couple small things to change. You should submit a PR so that more people can review the code though. @agramdass

How do i use the latest version to try on these changes? is it the following defined?

sequelize.sync({ alter: true })

and install sequelize 4.0?

Yeah, you need to install it from the github by npm-installing
sequelize/sequelize. 4.0.0 isn't out yet.

On Thu, May 25, 2017 at 7:50 AM, Pedro Victor de Sousa Lima <
[email protected]> wrote:

How do i use the latest version? is it the

sequelize.sync({ alter: true })

and install sequelize 4.0?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/sequelize/sequelize/issues/537#issuecomment-304029606,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABMIk367705eFbHCEit3goFf4bcKQezhks5r9ZUugaJpZM4AkYlY
.

@meyer9 What do you think about adding an option to preserve removed columns (probably by re-naming them, but I am open to other options). If there is support for this, I could create a PR. This would allow implementers to more safely keep schemas up to date, while being able to revert changes if necessary. Could also be great for that "oh shoot, I want that column after all" moment.

For example:

sequelize.sync({
    alter: true,
    preserveColumnsOnSync: true // PLEASE recommend a better name
})

This would add the following benefits:

  1. If you remove a column named foo of type Boolean from the schema, instead of removing that column, it will be re-named to something like __removed__foo__Boolean.
  2. If you re-add a column with the same name (foo) and same type back into the schema, your existing column will be used, being renamed back to foo.
  3. Data is not lost in the process
  4. Legacy data could be cleaned up safely at a later time, in a more deliberate manner.

It sounds like a good idea to me especially since this is only for
development/debugging. Also, possibly make this on by default. I'm sure
there will be users who use alter in production and I think it would be a
good safeguard against data loss.

On Sun, Aug 20, 2017 at 9:46 PM, Robby Emmert notifications@github.com
wrote:

@meyer9 https://github.com/meyer9 What do you think about adding an
option to preserve removed columns (probably by re-naming them, but I am
open to other options). If there is support for this, I could create a PR.
This would allow implementers to more safely keep schemas up to date, while
being able to revert changes if necessary. Could also be great for that "oh
shoot, I want that column after all" moment.

For example:

sequelize.sync({
alter: true,
preserveColumnsOnSync: true // PLEASE recommend a better name
})

This would add the following benefits:

  1. If you remove a column named foo of type Boolean from the schema,
    instead of removing that column, it will be re-named to something like
    __removed__foo__Boolean.
  2. If you re-add a column with the same name (foo) and same type back
    into the schema, your existing column will be used, being renamed back to
    foo.
  3. Data is not lost in the process
  4. Legacy data could be cleaned up safely at a later time, in a more
    deliberate manner.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/sequelize/sequelize/issues/537#issuecomment-323645364,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABMIk7A4qaXYPXMMCwOvo-r2JHktfKhGks5saQufgaJpZM4AkYlY
.

after testing alter: true in a moderate complex database -> many different kind of errors with relations, enums and what not. Seems like the best thing to do is keep away from all this automatic stuff as far away as you can and do your migrations by custom scripts or you are going to create the perfect scenario for a disaster... my two cents.

@manast I definitely agree with you. At snaplytics we do all migrations by hand as well

I disagree. It's not because it's complex that it's impossible. I have been using Doctrine ORM auto update with "ALTER TABLE" for years on countless PHP projects with complex databases and never get any issue with it (and you have the option to preview the queries about to be execute). I'm sorry but I really don't get the argument "Let's do all by hand it's better", especially for developers.

The sync({alter: true}) does not take in consideration the field attribute, atleast for MySql.

@v1r it also isn't working for sqlite. Is there additional configuration that needs to be set for this?

@kauffmanes nop, I am not sure for sqlite.

It would be very nice if the significant limitations of the tool are disclosed in a topic on the manual page.

Bump! Any progress on this?

The sync({alter: true}) does not take in consideration the field attribute, atleast for MySql.

I stumbled on the same issue today (I'm suing SQLite btw).
According to the API doc, this "Alters tables to fit models", but it doesn't run ALTER statements that are defined by queryInterface.changeColumn in migration files.

I wonder what sync({alter: true}) is supposed to do...?

Was this page helpful?
0 / 5 - 0 ratings