Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Database Update docs #769

Closed
morenoh149 opened this issue Dec 12, 2014 · 9 comments
Closed

Database Update docs #769

morenoh149 opened this issue Dec 12, 2014 · 9 comments
Assignees

Comments

@morenoh149
Copy link
Contributor

I'd love some documentation on how the updating mechanism works in keystonejs. Specifically, see updates/0.0.1-admin.js is

/**
 * This script automatically creates a default Admin user when an
 * empty database is used for the first time. You can use this
 * technique to insert data into any List you have defined.
 */

exports.create = {
  User: [{
    'name.first': 'Admin',
    'name.last': 'User',
    email: '[email protected]',
    password: 'dummypass', //replace this manually when you sign in
    isAdmin: true
  }]
};

/**
 * The following is the older version of this update script, it is
 * left here for reference as an example of how more complex updates
 * can be structured.
 */
/*
var keystone = require('keystone'),
  async = require('async'),
  User = keystone.list('User');

var admins = [{
  email: '[email protected]',
  password: 'admin',
  name: {
    first: 'Admin',
    last: 'User'
  }
}];

function createAdmin(admin, done) {

  var newAdmin = new User.model(admin);

  newAdmin.isAdmin = true;
  newAdmin.save(function(err) {
    if (err) {
      console.error("Error adding admin " + admin.email + " to the database:");
      console.error(err);
    } else {
      console.log("Added admin " + admin.email + " to the database.");
    }
    done(err);
  });
}

exports = module.exports = function(done) {
  async.forEach(admins, createAdmin, done);
};
*/

What update options are available? Can I deploy scripts that fill the database with dummy users? Can I deploy scripts that initialize the database with sample website copy that admins can later modify through the adminUI?

@webteckie
Copy link
Contributor

Invaluable tool! In exports.create{} you can initialize any list you want with whatever and as much data as you want. Once populated, you can mess with the db data as much as you want knowing that you can always reset it by dropping the db and restarting the server! The updates filename should be versioned. Keystone will keep track of the applied updates in mongo itself. Thus, if you restart your server it won't reapply the changes, unless you have dropped the entire db and/or explicitly removed the updates file entry in the db. You can enable verbose logging and strictness of the item creation process by including the following in your updates file:

exports.options = {
    verbose: true,
    strict: true
}

PS: @JedWatson, at least in windows systems, mongoose validation errors that happen during the item creation process are not logged by the updates module. However, logging them in the createItems function works fine. At some point I sent a PR that was logging the error in the createItems function but you thought it was best (as it should be) to have it logged in the updates module. However, that never worked for me! If people use this feature in windows system please be aware that you may get a very cryptic error when a mongoose validation error happens. To get around that you may need to log the error in createItems. Not sure the same problem happens under other OSs.

@morenoh149
Copy link
Contributor Author

leaving this here due to relevance https://github.com/marak/Faker.js/

@mgol
Copy link

mgol commented Nov 20, 2015

Is there any way to define updates that are not performed on fresh databases but are on existing ones? Say I change the schema of the model and I want to migrate older data. New data in new databases will have correct new schema from the beginning so updates assuming the older one would fail.

I can probably detect via duck-typing what shape the model is in and decide whether to apply updates only then but that seems fragile.

EDIT: never mind, old data is not there when the database is fresh so migrations are ignored then.

@antoineclaval
Copy link

@mgol I'm looking for a way to doing actual update too

@morenoh149 morenoh149 changed the title Database Update (migrations?) docs Database Update docs Jan 14, 2016
@morenoh149
Copy link
Contributor Author

the thing is mongo is "schemaless" so there is no need to stop the db to drop or add columns like in a tradtional RDBMS.

So I don't think tracking a database version number is necessary. To solve this issue I think all that would have to be documented is that any mongoose actions are valid within an update script. Ideally demonstrate filling the db with users, products and companies from the faker npm module.

@morenoh149 morenoh149 self-assigned this Jan 14, 2016
@antoineclaval
Copy link

What about updating a value, without changing the schema ?

@morenoh149 your first comment here create a user with [email protected] as a e-mail address. What if i want to create a migration script to change the e-mail address to [email protected] ?

@morenoh149
Copy link
Contributor Author

not sure. @JedWatson if I were to write an update script like

exports.findOneAndUpdate(
  { email: '[email protected]' },
  { email: '[email protected]' }
);

would that work? I'm reading through https://github.com/keystonejs/keystone/blob/master/lib/updates.js#L108

@webteckie
Copy link
Contributor

See this gist Basically in the updates file you can have a function that takes a callback. Thus, @morenoh149 example would be:

function(done) {

    // you can do whatever you want here and then make sure you call done(err).  For example:

    let myList = keystone.list('MyList');
    myList.model.findOneAndUpdate(
       { email: '[email protected]' },
       { email: '[email protected]' },
       done
    );
}

The shorthand syntax described in that gist is excellent for recreating text fixtures!

@mxstbr
Copy link
Collaborator

mxstbr commented Apr 29, 2016

Since this is a documentation issue, I've moved it to keystonejs/keystonejs-site#88!

@mxstbr mxstbr closed this as completed Apr 29, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants