使用StrongLoop自动创建MySQL表格

16

我正在尝试将Strongloop与 MySql 集成,但是无法弄清如何迁移或自动创建表格到 MySql 数据库。

是否至少有一种方法可以将模型导出到 MySql 模式中,还是我必须手动创建表格?

我一直在尝试使用 mysql 演示应用程序,并阅读文档了一段时间,但没有成功 - http://docs.strongloop.com/display/DOC/MySQL+connector

谢谢!


这是最干净的答案。其他所有答案都需要修改模型的数据源配置,这很容易出错。 - Overdrivr
8个回答

36

我创建了/server/boot/autoupdate.js。它在应用程序启动时运行。它加载“model-config”和“datasources” JSON,并将所有模型迁移或更新到为它们定义的数据源。

# /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();

};

运行得非常好!谢谢! - Marlon
1
这个过于复杂了。看看这个答案吧。 - Overdrivr
1
@Overdrivr提供的答案不完整,也无法处理所有情况,而这个答案可以。 - John Weldon
支持你的观点的论据?这段代码只是在重写已经在loopback-datasource-juggler中实现的内容。文档非常清晰。要迁移的模型。如果不存在,则应用于所有模型。自动更新也是如此。 - Overdrivr
这段代码也很糟糕,因为如果一个模型有一个配置错误的数据源不存在,它不会抛出错误,而只是跳过下一个模型并忽略它。 - Overdrivr
@jduhls:感谢您提供的脚本。所有模型都已迁移/更新,但在用户模型中,登录(/login)和注销(/logout)方法未生成(或未显示)在我的Loopback应用程序中。所有其他现有方法都像往常一样显示和工作。您能否为此问题提供解决方案!提前致谢 :-) - Prasad Kaiche

12

app.start方法之前,可以通过将以下行添加到您的server.js文件中来简单迁移模型:

app.datasources['mySqlConnection'].automigrate(['orders','customers', 'User', 'ACL'], function(err) {
     console.log(err);
});
  1. 根据您的需要将模型添加到数组中。
  2. 使用slc run运行应用程序。

注意:mySqlConnection是连接名称,请将其替换为您自己的连接名称。


当我再次运行应用程序时,我的数据丢失了。 - rkmax
是的,它会。因为当您再次运行迁移以创建已存在的表时,它将重新创建它们。如果您想迁移新表,则只需在自动迁移数组中传递这些表即可。 - Raviraj Chauhan
@Ben,这里有文档 https://docs.strongloop.com/display/public/LB/Creating+a+database+schema+from+models#Creatingadatabaseschemafrommodels-Auto-migrate - JacopKane
@rkmax 他们为那些有数据的表提供了自动更新方法。https://docs.strongloop.com/display/public/LB/Creating+a+database+schema+from+models#Creatingadatabaseschemafrommodels-Auto-update - JacopKane
我需要进行的一个小改动是将这些代码行放在 app.start(第一条语句)内部而不是之前。似乎数据源哈希表直到启动应用程序才会被加载。 - Arthur Frankel

10

要更新和/或创建模型的所有 MySQL 表:

var dataSource = app.dataSources.mysql;       
dataSource.autoupdate(null, function (err) {
    if(err) return cb(err);
    return cb();
});      

这应该是被接受的答案。实际上,当第一个参数为null时,autoupdateautomigrate函数将自动为所有服务器模型创建/更新数据源表。请参阅文档 - Overdrivr
6
你在哪里定义了这段代码?在启动文件中还是server.js中?这是否重要?有没有惯例? - adampetrie
我尝试在引导文件夹中使用JS,目前看起来运行良好。 - Miguel Hughes

8

2
谢谢,虽然我想我应该明确指出我已经一遍又一遍地阅读了那些文档,但还是无法弄清楚。当使用datasources.json定义我的数据库连接器时,我不确定在哪里和如何使用JS配置ds.automigrate(schema_v1.name, function () {} - glesage
1
第二个链接已经失效,不确定原始链接应该链接到哪里,但如果您能更新它,那就太好了。 - Félix Adriyel Gagnon-Grenier

1

在我的情况下,我手动创建了MySQL表格,然后创建了模型。对于现有的MySQL表格,我会创建与属性名称与MySQL字段名称相同的模型。

以下是我使用StrongLoop LoopBack与MySQL数据库的步骤:

  1. 创建MySQL数据库和表格(或使用现有的数据库)。
  2. 使用npm install loopback-connector-mysql --save安装MySQL连接器。
  3. datasources.json文件中添加你的MySQL数据库细节。
  4. 为每个表格创建一个模型,使用slc lb model tablename -i或编辑models.json文件并手动添加属性(文档:http://docs.strongloop.com/display/DOC/Creating+a+LoopBack+application#CreatingaLoopBackapplication-Creatingmodels)。
  5. 属性名称应与MySQL字段名称相同(更多信息关于将MySQL映射到JSON数据类型:http://docs.strongloop.com/display/DOC/MySQL+connector#MySQLconnector-MySQLtoJSONtypes)。

0
在同类问题中,如果您需要自动创建数据库,可以在数据源 JSON 文件中使用 createDatabase 选项。
  "mysql": {
    "host": "localhost",
    "port": 0,
    "database": "db",
    "username": "root",
    "password": "",
    "name": "mysql",
    "connector": "mysql",
    "debug": false,
    "createDatabase": true
  }

所以你不需要自己编写查询来创建基础。

希望能有所帮助。

这似乎没有在我的情况下创建数据库。 - Tom

0
jduhls的回答很好,但我需要稍微调整一下,将一些静态数据添加到表格中。这是我的修改版本,以及将数据加载到简单的SystemSettings表(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');
};

-1

我发现了一种简单的方法来完成这个任务。参考链接是:点击这里

你可以使用原型或不使用,在我的情况下,我没有使用。

关于文档,你应该使用:



    ds.autoupdate (models, function (error) {
        if (!error) {
            console.log( "Updated models.");
        }else{
            console.log( "An error has occurred:" + error);
        }
        ds.disconnect();
    });

在哪里:



    var path = require ( 'path');
    var app = require (path.resolve (__ dirname, '../server/server'));
    var ds = app.datasources.x;

x 是数据源属性名称,例如 /server/datasources.json 的示例:



    {
      "x": {
        "Host": "localhost"
        "Port": 3306,
        "Database", "loopapp"
        "Password": "",
        "Name": "x"
        "User", "root"
        "Connector": "mysql"
      }
    }

注意(1):模型可以是字符串模型名称或一个字符串数组(模型名称)。

注意(2):如果您不想放置模型,所有基属性等于“PersistedModel”的文件的所有模型将被更新。

因此,我像这样使用:

    autoupdate function () {
        ds.autoupdate (function (error) {
          if (!error) {
                console.log( "已更新所有模型" );
          }else {
                console.log( "发生错误:" + error);
          }
          ds.disconnect();
        });
    }
    

然后,我调用了:autoupdate();

您可以将此代码放入file.js文件中,并调用命令行:node file.js。

如果您希望每次启动程序时都调用此文件,请将其放在/server/boot/file.js路径下。

显然,如果您想要使用automigrate,则只需将上面的代码中的autoupdate单词替换为automigrate即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接