LoopBack calls it auto-migration. Check these links and search for that term:
Recipes for LoopBack Models, part 5 of 5: Model Synchronization with Relational Databases
Question
I am trying to use Strongloop with MySql but cannot figure out how to migrate or automatically create tables into a MySql database.
Is there at least a way to export the models into MySql schemas or do I have to manually create the tables?
I've been trying with the mysql demo app, and going over the docs for a while but no luck - http://docs.strongloop.com/display/DOC/MySQL+connector
Thanks!
Solution 4
LoopBack calls it auto-migration. Check these links and search for that term:
Recipes for LoopBack Models, part 5 of 5: Model Synchronization with Relational Databases
OTHER TIPS
I created /server/boot/autoupdate.js
. It runs when the app boots. It loads "model-config" and "datasources" JSON and migrates or updates all models to the datasources defined for them.
# /server/boot/autoupdate.js
module.exports = function(app) {
var path = require('path');
var models = require(path.resolve(__dirname, '../model-config.json'));
var datasources = require(path.resolve(__dirname, '../datasources.json'));
function autoUpdateAll(){
Object.keys(models).forEach(function(key) {
if (typeof models[key].dataSource != 'undefined') {
if (typeof datasources[models[key].dataSource] != 'undefined') {
app.dataSources[models[key].dataSource].autoupdate(key, function (err) {
if (err) throw err;
console.log('Model ' + key + ' updated');
});
}
}
});
}
function autoMigrateAll(){
Object.keys(models).forEach(function(key) {
if (typeof models[key].dataSource != 'undefined') {
if (typeof datasources[models[key].dataSource] != 'undefined') {
app.dataSources[models[key].dataSource].automigrate(key, function (err) {
if (err) throw err;
console.log('Model ' + key + ' migrated');
});
}
}
});
}
//TODO: change to autoUpdateAll when ready for CI deployment to production
autoMigrateAll();
//autoUpdateAll();
};
You can simply migrate models by adding following lines to your server.js file before app.start method:
app.datasources['mySqlConnection'].automigrate(['orders','customers', 'User', 'ACL'], function(err) {
console.log(err);
});
slc run
.Note:
mySqlConnection
is the connection name, replace it by your own connection name.
To update and/or create all mysql tables for your models:
var dataSource = app.dataSources.mysql;
dataSource.autoupdate(null, function (err) {
if(err) return cb(err);
return cb();
});
In my case, I manually created MySQL tables and then created the models. For existing MySQL tables, I create the models where property names are the same as MySQL field's names.
So here are my steps in using StrongLoop LoopBack with MySQL Database:
npm install loopback-connector-mysql --save
datasources.json
file.slc lb model tablename -i
OR edit models.json
file and add the properties manually. (document: http://docs.strongloop.com/display/DOC/Creating+a+LoopBack+application#CreatingaLoopBackapplication-Creatingmodels)In the same kind of issue, if you need to automatically create a database, you can use the createDatabase
option in your dataSource JSON file.
"mysql": {
"host": "localhost",
"port": 0,
"database": "db",
"username": "root",
"password": "",
"name": "mysql",
"connector": "mysql",
"debug": false,
"createDatabase": true
}
So you don't need to write yourself the queries to create the base. Hope it helps.
jduhls answer is beautiful, but I needed to tweak it slightly to add some static data into tables. Here's my tweaked version, along with an example of loading data into a simple SystemSettings table (id, settingName, settingValue):
var async = require('async');
var SYSTEM_SETTINGS = [
{
"settingName": "mustPayInAdvance",
"settingValue": "false",
}
];
module.exports = function(app) {
var path = require('path');
var models = require(path.resolve(__dirname, '../model-config.json'));
var datasources = require(path.resolve(__dirname, '../datasources.json'));
var modelUpdates = [];
function buildModelListForOperation(){
Object.keys(models).forEach(function(key) {
if (typeof models[key].dataSource != 'undefined') {
if (typeof datasources[models[key].dataSource] != 'undefined') {
modelUpdates.push({operation: app.dataSources[models[key].dataSource], key: key});
}
}
});
}
function createStaticData() {
app.models.SystemSettings.create(SYSTEM_SETTINGS, function(err, created) {
if (err)
throw err;
else
console.log('Sample data was imported.');
});
}
function processModelsAndData(operationType) {
buildModelListForOperation();
// Create all models
async.each(modelUpdates, function(item, callback) {
item.operation[operationType](item.key, function (err) {
if (err) throw err;
console.log('Model ' + item.key + ' migrated');
callback();
});
}, function (err) {
if (err) throw err;
createStaticData();
});
}
//TODO: change to 'autoupdate' when ready for CI deployment to production
processModelsAndData('automigrate');
};
i discovered an easy way to accomplish this task. The reference link is: Clique Here
You can use prototype or not, in my case, i do nott used.
For the documentation, you should use:
ds.autoupdate (models, function (error) {
if (!error) {
console.log( "Updated models.");
}else{
console.log( "An error has occurred:" + error);
}
ds.disconnect();
});
Where:
var path = require ( 'path');
var app = require (path.resolve (__ dirname, '../server/server'));
var ds = app.datasources.x;
and x is datasource attribute name, example of /server/datasources.json:
{
"x": {
"Host": "localhost"
"Port": 3306,
"Database", "loopapp"
"Password": "",
"Name": "x"
"User", "root"
"Connector": "mysql"
}
}
Note (1): Models can be the string model name or the array of string (models names).
Note (2): If you prefer not to put models, all models of the file whose base attribute equals "PersistedModel", will be updated.
With that, i used like this:
autoupdate function () { ds.autoupdate (function (error) { if (!error) { console.log( "Updated all models"); }else { console.log( "An error has occurred:" + error); } ds.disconnect(); }); }
and i called the: autoupdate();
You can put this code in a file.js and call the command line: node file.js.
If you want this file to be called every time you start the program, put it on /server/boot/file.js path.
Obviously, if you want to use automigrate, only replace the autoupdate word in the code above, by automigrate.