Sails.js 中单个模型的多个表?
Multiple tables for a single model in Sails.js?
我目前有一个用 Perl 编写的网站,使用 Mojolicious and Mojo::Pg。它所做的其中一件事是从我的 Ninja Block 的温度传感器中获取并显示数据。我在 Postgres 中有四个 table,outdoor_temperature
,outdoor_humidity
,在室内也是如此。 table 看起来像这样:
Column | Type | Modifiers
--------+---------+-----------
time | bigint | not null
value | numeric | not null
date | date | not null
其中 time
是以毫秒为单位的纪元值(每分钟一条记录),value
是温度或湿度,date
就是这样(所以每条记录一个给定日期在 date
列中具有相同的值)。
我正在使用 Node 和 Sails.js 重写网站,主要是为了学习机会,我有点坚持在这里做事的最佳方式。在它的 Perl 化身中,我为每个与 Ninja Block 相关的功能(显示今天的当前温度,显示给定日期的 highest/lowest 等)都有一个子例程,我传递它的位置(室内或户外),一切都从那里开始,像这样:
sub current {
my ( $self, $table ) = @_;
return $self->pg->db->query( "select time, value from $table where time = (select max(time) from $table)" )->hash;
}
但是对于Sails/Waterline,似乎一个模型只包含一个table。在我的 Perl 版本中,任何 table 之间都没有连接,只有一些对每个人 table 的半复杂 SQL 查询,我可以使用 .query
在 Sails 中完成这些查询,但我不确定如何在 Sails 下保留相同的设置,而无需在检查室内和室外时复制一堆代码 tables.
还是我完全错误地考虑了这个问题,有更好的方法来完成这一切?
我最终选择了一个位于控制器和模型之间的服务。控制器函数如下所示(使用与上面相同的示例):
currentTemperature: function(req, res) {
ninjaBlockService.getCurrentTemperature(req.param('location'), function(data) {
return res.json(data);
});
}
以及服务函数:
getCurrentTemperature: function(location, callback) {
var query = "select time, value from " + location + "_temperature where time = (select max(time) from " + location + "_temperature)";
var locations = {
outdoor: function() {
NinjaBlockOutdoorTemperature.query(query, function(err, results) {
return callback(results.rows);
});
},
indoor: function() {
NinjaBlockIndoorTemperature.query(query, function(err, results) {
return callback(results.rows);
});
}
};
locations[location]();
}
它可能会更优雅一些,但对我来说效果很好。
因此,事实证明,如果您使用的是 Waterline 的 PostgreSQL 本机 .query
,您甚至不需要针对多个 table 的多个模型。我添加了一个名为 NinjaBlock
的新模型,它没有任何属性或任何东西,并且可以 运行 我的查询,无论它们在哪个 table 中。所以上面的函数现在看起来像这样相反:
getCurrentTemperature: function(location, callback) {
var query = "select time, value from " + location + "_temperature where time = (select max(time) from " + location + "_temperature)";
NinjaBlock.query(query, function(err, results) {
return callback(results.rows);
});
}
简单!
我目前有一个用 Perl 编写的网站,使用 Mojolicious and Mojo::Pg。它所做的其中一件事是从我的 Ninja Block 的温度传感器中获取并显示数据。我在 Postgres 中有四个 table,outdoor_temperature
,outdoor_humidity
,在室内也是如此。 table 看起来像这样:
Column | Type | Modifiers
--------+---------+-----------
time | bigint | not null
value | numeric | not null
date | date | not null
其中 time
是以毫秒为单位的纪元值(每分钟一条记录),value
是温度或湿度,date
就是这样(所以每条记录一个给定日期在 date
列中具有相同的值)。
我正在使用 Node 和 Sails.js 重写网站,主要是为了学习机会,我有点坚持在这里做事的最佳方式。在它的 Perl 化身中,我为每个与 Ninja Block 相关的功能(显示今天的当前温度,显示给定日期的 highest/lowest 等)都有一个子例程,我传递它的位置(室内或户外),一切都从那里开始,像这样:
sub current {
my ( $self, $table ) = @_;
return $self->pg->db->query( "select time, value from $table where time = (select max(time) from $table)" )->hash;
}
但是对于Sails/Waterline,似乎一个模型只包含一个table。在我的 Perl 版本中,任何 table 之间都没有连接,只有一些对每个人 table 的半复杂 SQL 查询,我可以使用 .query
在 Sails 中完成这些查询,但我不确定如何在 Sails 下保留相同的设置,而无需在检查室内和室外时复制一堆代码 tables.
还是我完全错误地考虑了这个问题,有更好的方法来完成这一切?
我最终选择了一个位于控制器和模型之间的服务。控制器函数如下所示(使用与上面相同的示例):
currentTemperature: function(req, res) {
ninjaBlockService.getCurrentTemperature(req.param('location'), function(data) {
return res.json(data);
});
}
以及服务函数:
getCurrentTemperature: function(location, callback) {
var query = "select time, value from " + location + "_temperature where time = (select max(time) from " + location + "_temperature)";
var locations = {
outdoor: function() {
NinjaBlockOutdoorTemperature.query(query, function(err, results) {
return callback(results.rows);
});
},
indoor: function() {
NinjaBlockIndoorTemperature.query(query, function(err, results) {
return callback(results.rows);
});
}
};
locations[location]();
}
它可能会更优雅一些,但对我来说效果很好。
因此,事实证明,如果您使用的是 Waterline 的 PostgreSQL 本机 .query
,您甚至不需要针对多个 table 的多个模型。我添加了一个名为 NinjaBlock
的新模型,它没有任何属性或任何东西,并且可以 运行 我的查询,无论它们在哪个 table 中。所以上面的函数现在看起来像这样相反:
getCurrentTemperature: function(location, callback) {
var query = "select time, value from " + location + "_temperature where time = (select max(time) from " + location + "_temperature)";
NinjaBlock.query(query, function(err, results) {
return callback(results.rows);
});
}
简单!