0

我有一个应用程序将用户上传的电子表格存储为 PostgreSQL 中的表。Dataset每次用户上传电子表格时,我都会在包含物理表名称、别名和所有者的表中创建一条记录。我可以使用检索某个数据集信息

GET domain.com/v1/Datasets/{id}

AFAIK,行和物理表之间的关系Dataset不能由 FK 强制执行,或者至少我还没有看到有人在 PostgreSQL 的 information_schema 上创建 FK,并且 FK 不能删除表,或者他们可以吗?因此,通常会有孤立表,或者 Dataset 该点中的记录指向不再存在的表。我已经通过业务逻辑和清理任务来管理这个。

现在,要访问其中一个物理表,例如一个名为nba_teamsI 的表,我需要在环回中声明一个 NbaTeams 模型并重新启动应用程序,然后使用查询其记录

GET domain.com/v1/NbaTeams/{id}

但这无法扩展,特别是如果我每天已经有 100 次上传。所以从我的立场来看,有两条路可以走:

1.- 创建一个模型,然后添加 4 个接受表名作为字符串的自定义方法,并通过原始查询对该表名执行下一个 CRUD 操作。例如,要列出记录:

GET domain.com/v1/Datasets/getTable/NbaTeams

或者,更新一个团队

PUT domain.com/v1/Datasets/getTable/NbaTeams/{teamId}

这听起来不优雅,但应该有效。

2.- 创建一个接受表名作为字符串的自定义方法,该方法反过来创建一个临时模型并将 HTTP 动词和其余参数转发给它

dataSource.discoverAndBuildModels('nba_teams', {
    owner: 'uploader'
}, function (err, models) {
    console.log(models);
    models.NbaTeams.find(function (err, act) {
        if (err) {
            console.error(err);
        } else {
            console.log(act);
        }
        dataSource.disconnect();
    });
});

第二个我还没有开始工作,我不知道它可能有多少开销,但我确信它是可行的。

所以在我深入挖掘之前,我来问:有人处理过这种行到表的关系吗?这方面有哪些好的做法

4

1 回答 1

1

最后,我做了自己的 hacky 解决方法,我认为有一天它可能会帮助某人。

我所做的是放置一个中间件(使用正则表达式语法)来监听 /v1/dataset{id_dataset} ,动态创建模型并将执行传递给下一个中间件

app.use('/v1/dataset:id_dataset', function(req, res, next) {
    var idDataset=req.params.id_dataset;
    app.getTheTable(idDataset,function(err,result) {
        if(err) { 
          console.error(err);
          res.json({"error":"couldn't retrieve related table"});
        } else {
          next();
        }
    });
});

app.getTheTable函数内部,我正在动态创建模型并在回调之前对其进行设置

app.getTheTable = function (idDataset, callback) {
    var Table = app.models.Dataset,
    modelName='dataset'+idDataset,
    dataSource;

    Table.findById(idDataset, function (err, resultados) {
        if (err) {
            callback(new Error('Unauthorized'));
        } else {
           if(app.models[modelName]) {
               callback(null,modelName); // model already exists
           } else {
               var theDataset = dataSource.createModel(modelName, properties, options);
               theDataset.settings.plural = modelName;
               theDataset.setup();

               app.model(theDataset);
               var restApiRoot = app.get('restApiRoot');
               app.use(restApiRoot, app.loopback.rest());

               callback(null, modelName);
           }
        }
    });
};

我知道这很麻烦,而且我相信重载 restApiRoot 中间件肯定会造成某种性能损失,但最好还是在启动时创建 500 个模型来覆盖所有可能的数据集请求。

于 2014-11-13T13:09:06.967 回答