【问题标题】:Clean method for declaring models声明模型的清洁方法
【发布时间】:2025-11-21 07:45:03
【问题描述】:

我有一个使用 express、orm 和 sqlite3 的节点项目。

我有多个模型。目前每个模型的声明类似于:

var orm = require('orm');
var db = orm.connect({database: ':memory:', protocol: 'sqlite'});
var schema = db.define('service', {
    uptime: Number,
    // ...
});
db.sync(function (err) {
    !err && console.log("db synced!");
});
module.exports = schema;

在十几个模型中重复要求和连接并不是特别愉快。

我想整理一下,这样我就可以连接到app.js,然后加载模型并像往常一样在路线中使用它们。但是我无法让它工作。这就是我正在做的:

首先我在app.js中定义连接和模型:

var service;
orm.connect(app.get('db-opt'), function(err,db){
    !err && console.log("db connected!");
    if (err){
        throw err;
    }
    db.load('./models', function(err){
        app.service = service = db.models.service;
        !err && console.log("models loaded!");
    });
    db.sync(function(err){
        !err && console.log("db synced!");
    });
});

models/index.js 文件如下所示:

module.exports = function(db,fn){
    db.define('service', {
        uptime: Number,
        // ...
    });
    return fn();
};

routes/services.js 看起来像:

var services = [];

exports.list = function(service){
    return function(req, res){
        service.find({}, function(err, services){
            if (err){
                return next(err);
            }
            res.render('services', {
                title: 'Services',
                services: services
            });
        });
    };
};

最后我在 app.js 中像这样连接路由:

app.get('/services', services.list(service));

我收到了预期的控制台消息,但当我尝试访问时,我收到以下错误: TypeError: Cannot call method 'find' of undefined.

我已尝试将 app.servicemodels.service 传递给 service.list,但都没有给出相同的错误。

我怎样才能干净地加载模型并让需要它们的路由可以访问它们?

更新:我可以证明db.load 调用正在使用以下代码:

db.load('./models', function(err){
    var services = [];
    service = db.models.service;
    service.find({}, function(err, services) {
        if (err){
            throw err;
        }
    });
    !err && console.log("models loaded!");
});

因为这给出了Error: SQLITE_ERROR: no such table: service

【问题讨论】:

    标签: node.js sqlite express


    【解决方案1】:

    看来我很接近了。我假设app.get('/', services.list(service)); 会在调用时使用服务中的任何值来调用。因此,尽管app.get(...)orm.connect 的回调之前(可能)被执行,但在http.createServer(app) 之后,一切都会得到正确解决。不是这样。

    app.get(..) 移动到 orm.connect 回调中会使其工作。

    因此:

    // define models
    var db = orm.connect(app.get('db-opt'), function(err,db){
        !err && console.log("db connected!");
        if (err){
            throw err;
        }
        db.load('./models', function(err){
            app.service = db.models.service;
            !err && console.log("models loaded!");
        });
        db.sync(function(err){
            !err && console.log("db synced!");
        });
    
        app.get('/', services.list(app.service));
        // ...
    });
    

    虽然这是我将使用的方法,但任何人都可以看到不同的方法吗?

    【讨论】:

      最近更新 更多